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 static android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_STATE; 20 import static android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_STATE_COMPAT; 21 import static android.adservices.common.AdServicesPermissions.MODIFY_ADSERVICES_STATE; 22 import static android.adservices.common.AdServicesPermissions.MODIFY_ADSERVICES_STATE_COMPAT; 23 import static android.adservices.common.AdServicesPermissions.UPDATE_PRIVILEGED_AD_ID; 24 import static android.adservices.common.AdServicesPermissions.UPDATE_PRIVILEGED_AD_ID_COMPAT; 25 import static android.adservices.common.AndroidRCommonUtil.invokeCallbackOnErrorOnRvc; 26 27 import android.adservices.adid.AdId; 28 import android.annotation.CallbackExecutor; 29 import android.annotation.FlaggedApi; 30 import android.annotation.IntDef; 31 import android.annotation.NonNull; 32 import android.annotation.RequiresPermission; 33 import android.annotation.SdkConstant; 34 import android.annotation.SdkConstant.SdkConstantType; 35 import android.annotation.SystemApi; 36 import android.app.sdksandbox.SandboxedSdkContext; 37 import android.content.Context; 38 import android.os.Build; 39 import android.os.OutcomeReceiver; 40 import android.os.RemoteException; 41 import android.os.SystemClock; 42 43 import androidx.annotation.RequiresApi; 44 45 import com.android.adservices.AdServicesCommon; 46 import com.android.adservices.LogUtil; 47 import com.android.adservices.ServiceBinder; 48 import com.android.adservices.flags.Flags; 49 50 import java.lang.annotation.Retention; 51 import java.lang.annotation.RetentionPolicy; 52 import java.util.Objects; 53 import java.util.concurrent.Executor; 54 55 /** 56 * AdServicesCommonManager contains APIs common across the various AdServices. It provides two 57 * SystemApis: 58 * 59 * <ul> 60 * <li>isAdServicesEnabled - allows to get AdServices state. 61 * <li>setAdServicesEntryPointEnabled - allows to control AdServices state. 62 * </ul> 63 * 64 * <p>The instance of the {@link AdServicesCommonManager} can be obtained using {@link 65 * Context#getSystemService} and {@link AdServicesCommonManager} class. 66 * 67 * @hide 68 */ 69 @SystemApi 70 public class AdServicesCommonManager { 71 /** @hide */ 72 public static final String AD_SERVICES_COMMON_SERVICE = "ad_services_common_service"; 73 74 private final Context mContext; 75 private final ServiceBinder<IAdServicesCommonService> mAdServicesCommonServiceBinder; 76 77 // TODO(b/378923974): refactor all usages to reference these constants directly instead of 78 // derived ones in other classes. 79 80 /** Don't show any notification during the enrollment. */ 81 @FlaggedApi(Flags.FLAG_ADSERVICES_ENABLE_PER_MODULE_OVERRIDES_API) 82 public static final int NOTIFICATION_NONE = 0; 83 84 /** Shows ongoing notification during the enrollment, which user can not dismiss. */ 85 @FlaggedApi(Flags.FLAG_ADSERVICES_ENABLE_PER_MODULE_OVERRIDES_API) 86 public static final int NOTIFICATION_ONGOING = 1; 87 88 /** Shows regular notification during the enrollment, which user can dismiss. */ 89 @FlaggedApi(Flags.FLAG_ADSERVICES_ENABLE_PER_MODULE_OVERRIDES_API) 90 public static final int NOTIFICATION_REGULAR = 2; 91 92 /** 93 * Result codes that are common across various APIs. 94 * 95 * @hide 96 */ 97 @IntDef(value = {NOTIFICATION_NONE, NOTIFICATION_ONGOING, NOTIFICATION_REGULAR}) 98 @Retention(RetentionPolicy.SOURCE) 99 public @interface NotificationType {} 100 101 /** Default user choice state */ 102 @FlaggedApi(Flags.FLAG_ADSERVICES_ENABLE_PER_MODULE_OVERRIDES_API) 103 public static final int USER_CHOICE_UNKNOWN = 0; 104 105 /** User opted in state */ 106 @FlaggedApi(Flags.FLAG_ADSERVICES_ENABLE_PER_MODULE_OVERRIDES_API) 107 public static final int USER_CHOICE_OPTED_IN = 1; 108 109 /** User opted out state */ 110 @FlaggedApi(Flags.FLAG_ADSERVICES_ENABLE_PER_MODULE_OVERRIDES_API) 111 public static final int USER_CHOICE_OPTED_OUT = 2; 112 113 /** 114 * Result codes that are common across various modules. 115 * 116 * @hide 117 */ 118 @IntDef( 119 prefix = {""}, 120 value = {USER_CHOICE_UNKNOWN, USER_CHOICE_OPTED_IN, USER_CHOICE_OPTED_OUT}) 121 @Retention(RetentionPolicy.SOURCE) 122 public @interface ModuleUserChoice {} 123 124 /** Default module state */ 125 @FlaggedApi(Flags.FLAG_ADSERVICES_ENABLE_PER_MODULE_OVERRIDES_API) 126 public static final int MODULE_STATE_UNKNOWN = 0; 127 128 /** Module is available on the device */ 129 @FlaggedApi(Flags.FLAG_ADSERVICES_ENABLE_PER_MODULE_OVERRIDES_API) 130 public static final int MODULE_STATE_ENABLED = 1; 131 132 /** Module is not available on the device */ 133 @FlaggedApi(Flags.FLAG_ADSERVICES_ENABLE_PER_MODULE_OVERRIDES_API) 134 public static final int MODULE_STATE_DISABLED = 2; 135 136 /** 137 * Result codes that are common across various modules. 138 * 139 * @hide 140 */ 141 @IntDef( 142 prefix = {""}, 143 value = {MODULE_STATE_UNKNOWN, MODULE_STATE_ENABLED, MODULE_STATE_DISABLED}) 144 @Retention(RetentionPolicy.SOURCE) 145 public @interface ModuleState {} 146 147 /** Measurement module. */ 148 @FlaggedApi(Flags.FLAG_ADSERVICES_ENABLE_PER_MODULE_OVERRIDES_API) 149 public static final int MODULE_MEASUREMENT = 0; 150 151 /** Privacy Sandbox module. */ 152 @FlaggedApi(Flags.FLAG_ADSERVICES_ENABLE_PER_MODULE_OVERRIDES_API) 153 public static final int MODULE_PROTECTED_AUDIENCE = 1; 154 155 /** Privacy Sandbox Attribution module. */ 156 @FlaggedApi(Flags.FLAG_ADSERVICES_ENABLE_PER_MODULE_OVERRIDES_API) 157 public static final int MODULE_PROTECTED_APP_SIGNALS = 2; 158 159 /** Topics module. */ 160 @FlaggedApi(Flags.FLAG_ADSERVICES_ENABLE_PER_MODULE_OVERRIDES_API) 161 public static final int MODULE_TOPICS = 3; 162 163 /** On-device Personalization(ODP) module. */ 164 @FlaggedApi(Flags.FLAG_ADSERVICES_ENABLE_PER_MODULE_OVERRIDES_API) 165 public static final int MODULE_ON_DEVICE_PERSONALIZATION = 4; 166 167 /** ADID module. */ 168 @FlaggedApi(Flags.FLAG_ADSERVICES_ENABLE_PER_MODULE_OVERRIDES_API) 169 public static final int MODULE_ADID = 5; 170 171 /** 172 * ModuleCode IntDef. 173 * 174 * @hide 175 */ 176 @IntDef( 177 value = { 178 MODULE_MEASUREMENT, 179 MODULE_PROTECTED_AUDIENCE, 180 MODULE_PROTECTED_APP_SIGNALS, 181 MODULE_TOPICS, 182 MODULE_ON_DEVICE_PERSONALIZATION, 183 MODULE_ADID 184 }) 185 @Retention(RetentionPolicy.SOURCE) 186 public @interface Module {} 187 188 /** 189 * Returns {@code module} or throws an {@link IllegalArgumentException} if it's invalid. 190 * 191 * @param module module to validate 192 * @hide 193 */ 194 @Module validateModule(@odule int module)195 public static int validateModule(@Module int module) { 196 return switch (module) { 197 case MODULE_ADID, 198 MODULE_MEASUREMENT, 199 MODULE_ON_DEVICE_PERSONALIZATION, 200 MODULE_PROTECTED_APP_SIGNALS, 201 MODULE_PROTECTED_AUDIENCE, 202 MODULE_TOPICS -> 203 module; 204 default -> throw new IllegalArgumentException("Invalid Module:" + module); 205 }; 206 } 207 208 /** 209 * Returns {@code moduleState} or throws an {@link IllegalArgumentException} if it's invalid. 210 * 211 * @param moduleState module state to validate 212 * @hide 213 */ 214 @ModuleState validateModuleState(@oduleState int moduleState)215 public static int validateModuleState(@ModuleState int moduleState) { 216 return switch (moduleState) { 217 case MODULE_STATE_UNKNOWN, MODULE_STATE_ENABLED, MODULE_STATE_DISABLED -> moduleState; 218 default -> throw new IllegalArgumentException("Invalid Module State:" + moduleState); 219 }; 220 } 221 222 /** 223 * Create AdServicesCommonManager. 224 * 225 * @hide 226 */ 227 public AdServicesCommonManager(@NonNull Context context) { 228 mContext = context; 229 mAdServicesCommonServiceBinder = 230 ServiceBinder.getServiceBinder( 231 context, 232 AdServicesCommon.ACTION_AD_SERVICES_COMMON_SERVICE, 233 IAdServicesCommonService.Stub::asInterface); 234 } 235 236 /** 237 * Factory method for creating an instance of AdServicesCommonManager. 238 * 239 * @param context The {@link Context} to use 240 * @return A {@link AdServicesCommonManager} instance 241 */ 242 @NonNull 243 public static AdServicesCommonManager get(@NonNull Context context) { 244 // On T+, context.getSystemService() does more than just call constructor. 245 return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) 246 ? context.getSystemService(AdServicesCommonManager.class) 247 : new AdServicesCommonManager(context); 248 } 249 250 @NonNull 251 private IAdServicesCommonService getService() { 252 IAdServicesCommonService service = mAdServicesCommonServiceBinder.getService(); 253 if (service == null) { 254 throw new IllegalStateException("Unable to find the service"); 255 } 256 return service; 257 } 258 259 /** 260 * Get the AdService's enablement state which represents whether AdServices feature is enabled 261 * or not. This API is for Android S+, which has the OutcomeReceiver class available. 262 * 263 * @hide 264 */ 265 @SystemApi 266 @RequiresPermission(anyOf = {ACCESS_ADSERVICES_STATE, ACCESS_ADSERVICES_STATE_COMPAT}) 267 @RequiresApi(Build.VERSION_CODES.S) 268 public void isAdServicesEnabled( 269 @NonNull @CallbackExecutor Executor executor, 270 @NonNull OutcomeReceiver<Boolean, Exception> callback) { 271 final IAdServicesCommonService service = getService(); 272 try { 273 service.isAdServicesEnabled( 274 new IAdServicesCommonCallback.Stub() { 275 @Override 276 public void onResult(IsAdServicesEnabledResult result) { 277 executor.execute( 278 () -> { 279 callback.onResult(result.getAdServicesEnabled()); 280 }); 281 } 282 283 @Override 284 public void onFailure(int statusCode) { 285 executor.execute( 286 () -> 287 callback.onError( 288 AdServicesStatusUtils.asException(statusCode))); 289 } 290 }); 291 } catch (RemoteException e) { 292 LogUtil.e(e, "RemoteException"); 293 executor.execute( 294 () -> callback.onError(new IllegalStateException("Internal Error!", e))); 295 } 296 } 297 298 /** 299 * Get the AdService's enablement state which represents whether AdServices feature is enabled 300 * or not. This API is for Android R, and uses the AdServicesOutcomeReceiver class because 301 * OutcomeReceiver is not available. 302 * 303 * @deprecated use {@link #isAdServicesEnabled(Executor, OutcomeReceiver)} instead. Android R is 304 * no longer supported. 305 * @hide 306 */ 307 @SystemApi 308 @RequiresPermission(anyOf = {ACCESS_ADSERVICES_STATE, ACCESS_ADSERVICES_STATE_COMPAT}) 309 @Deprecated 310 @FlaggedApi(Flags.FLAG_ADSERVICES_OUTCOMERECEIVER_R_API_DEPRECATED) 311 @SuppressWarnings("NewApi") 312 public void isAdServicesEnabled( 313 @NonNull @CallbackExecutor Executor executor, 314 @NonNull AdServicesOutcomeReceiver<Boolean, Exception> callback) { 315 316 if (invokeCallbackOnErrorOnRvc(callback)) { 317 return; 318 } 319 320 isAdServicesEnabled(executor, OutcomeReceiverConverter.toOutcomeReceiver(callback)); 321 } 322 323 /** 324 * Sets the AdService's enablement state based on the provided parameters. 325 * 326 * <p>As a result of the AdServices state, {@code adServicesEntryPointEnabled}, {@code 327 * adIdEnabled}, appropriate notification may be displayed to the user. It's displayed only once 328 * when all the following conditions are met: 329 * 330 * <ul> 331 * <li>AdServices state - enabled. 332 * <li>adServicesEntryPointEnabled - true. 333 * </ul> 334 * 335 * @param adServicesEntryPointEnabled indicate entry point enabled or not 336 * @param adIdEnabled indicate user opt-out of adid or not 337 * @hide 338 */ 339 @SystemApi 340 @RequiresPermission(anyOf = {MODIFY_ADSERVICES_STATE, MODIFY_ADSERVICES_STATE_COMPAT}) 341 public void setAdServicesEnabled(boolean adServicesEntryPointEnabled, boolean adIdEnabled) { 342 final IAdServicesCommonService service = getService(); 343 try { 344 service.setAdServicesEnabled(adServicesEntryPointEnabled, adIdEnabled); 345 } catch (RemoteException e) { 346 LogUtil.e(e, "RemoteException"); 347 } 348 } 349 350 /** 351 * Enable AdServices based on the AdServicesStates input parameter. This API is for Android S+, 352 * which has the OutcomeReceiver class available. 353 * 354 * <p>Based on the provided {@code AdServicesStates}, AdServices may be enabled. Specifically, 355 * users will be provided with an enrollment channel (such as notification) to become privacy 356 * sandbox users when: 357 * 358 * <ul> 359 * <li>isAdServicesUiEnabled - true. 360 * <li>isU18Account | isAdultAccount - true. 361 * </ul> 362 * 363 * @param {@code AdServicesStates} parcel containing relevant AdServices state variables. 364 * @return false if API is disabled, true if the API call completed successfully. Otherwise, it 365 * would return one of the following exceptions to the user: 366 * <ul> 367 * <li>IllegalStateException - the default exception thrown when service crashes 368 * unexpectedly. 369 * <li>SecurityException - when the caller is not authorized to call this API. 370 * <li>TimeoutException - when the services takes too long to respond. 371 * </ul> 372 * 373 * @hide 374 */ 375 @SystemApi 376 @RequiresPermission(anyOf = {MODIFY_ADSERVICES_STATE, MODIFY_ADSERVICES_STATE_COMPAT}) 377 @RequiresApi(Build.VERSION_CODES.S) 378 public void enableAdServices( 379 @NonNull AdServicesStates adServicesStates, 380 @NonNull @CallbackExecutor Executor executor, 381 @NonNull OutcomeReceiver<Boolean, Exception> callback) { 382 Objects.requireNonNull(adServicesStates); 383 Objects.requireNonNull(executor); 384 Objects.requireNonNull(callback); 385 386 final IAdServicesCommonService service = getService(); 387 try { 388 service.enableAdServices( 389 adServicesStates, 390 new IEnableAdServicesCallback.Stub() { 391 @Override 392 public void onResult(EnableAdServicesResponse response) { 393 executor.execute( 394 () -> { 395 if (!response.isApiEnabled()) { 396 callback.onResult(false); 397 return; 398 } 399 400 if (response.isSuccess()) { 401 callback.onResult(true); 402 } else { 403 callback.onError( 404 AdServicesStatusUtils.asException( 405 response.getStatusCode())); 406 } 407 }); 408 } 409 410 @Override 411 public void onFailure(int statusCode) { 412 executor.execute( 413 () -> 414 callback.onError( 415 AdServicesStatusUtils.asException(statusCode))); 416 } 417 }); 418 } catch (RemoteException e) { 419 LogUtil.e(e, "RemoteException"); 420 executor.execute( 421 () -> callback.onError(new IllegalStateException("Internal Error!", e))); 422 } 423 } 424 425 /** 426 * Broadcast action: notify that a consent notification has been displayed to the user, and the 427 * user consent choices can be set by calling {@link #requestAdServicesModuleUserChoices()}. 428 * 429 * <p>The action must be defined as an intent-filter in AndroidManifest.xml in order to receive 430 * Intents from the platform. 431 * 432 * @hide 433 */ 434 @SystemApi 435 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 436 @FlaggedApi(Flags.FLAG_ADSERVICES_ENABLE_PER_MODULE_OVERRIDES_API) 437 @RequiresPermission(anyOf = {MODIFY_ADSERVICES_STATE, MODIFY_ADSERVICES_STATE_COMPAT}) 438 public static final String ACTION_ADSERVICES_NOTIFICATION_DISPLAYED = 439 "android.adservices.common.action.ADSERVICES_NOTIFICATION_DISPLAYED"; 440 441 /** 442 * Activity Action: Open the consent landing page activity. In the activity, user consent 443 * choices can be set, depending on user action, by calling {@link 444 * #requestAdServicesModuleUserChoices()}. The action must be defined as an intent-filter in 445 * AndroidManifest.xml in order to receive Intents from the platform. 446 * 447 * <p>Input: nothing 448 * 449 * <p>Output: nothing 450 * 451 * @hide 452 */ 453 @SystemApi 454 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) 455 @FlaggedApi(Flags.FLAG_ADSERVICES_ENABLE_PER_MODULE_OVERRIDES_API) 456 @RequiresPermission(anyOf = {MODIFY_ADSERVICES_STATE, MODIFY_ADSERVICES_STATE_COMPAT}) 457 public static final String ACTION_VIEW_ADSERVICES_CONSENT_PAGE = 458 "android.adservices.common.action.VIEW_ADSERVICES_CONSENT_PAGE"; 459 460 /** 461 * Sets overrides for the AdServices Module(s). 462 * 463 * <p>This API can enable/disable AdServices modules. Setting a module to off will hide the 464 * settings controls for any PPAPIs (Privacy Preserving APIs) associated with it. In addition, 465 * those PPAPIs will not operate for that user. 466 * 467 * <p>A notification type is also required to determine what type of notification should be 468 * shown to the user to notify them of these changes. The NotificationType can be Ongoing, 469 * Regular, or None. 470 * 471 * @param updateParams object containing state information for modules and notification type. 472 * @param executor the executor for the callback. 473 * @param callback callback function to confirm modules overrides is set up correctly. 474 * @hide 475 */ 476 @SystemApi 477 @FlaggedApi(Flags.FLAG_ADSERVICES_ENABLE_PER_MODULE_OVERRIDES_API) 478 @RequiresPermission(anyOf = {MODIFY_ADSERVICES_STATE, MODIFY_ADSERVICES_STATE_COMPAT}) 479 public void requestAdServicesModuleOverrides( 480 @NonNull UpdateAdServicesModuleStatesParams updateParams, 481 @NonNull @CallbackExecutor Executor executor, 482 @NonNull AdServicesOutcomeReceiver<Void, Exception> callback) { 483 Objects.requireNonNull(updateParams, "updateParams cannot be null"); 484 Objects.requireNonNull(executor, "executor cannot be null"); 485 Objects.requireNonNull(callback, "callback cannot be null"); 486 487 if (invokeCallbackOnErrorOnRvc(callback)) { 488 return; 489 } 490 491 final IAdServicesCommonService service = getService(); 492 try { 493 service.requestAdServicesModuleOverrides( 494 updateParams, 495 new IRequestAdServicesModuleOverridesCallback.Stub() { 496 @Override 497 public void onSuccess() throws RemoteException { 498 callback.onResult(null); 499 } 500 501 @Override 502 public void onFailure(int statusCode) throws RemoteException { 503 callback.onError( 504 new IllegalStateException( 505 "Internal Error! status code: " + statusCode)); 506 } 507 }); 508 } catch (RemoteException e) { 509 LogUtil.e(e, "RemoteException"); 510 executor.execute( 511 () -> callback.onError(new IllegalStateException("Internal Error!", e))); 512 } 513 } 514 515 /** 516 * Sets the user choices for AdServices Module(s). 517 * 518 * <p>This API sets the user consent value for each AdServices module (PAS, Measurement, Topic, 519 * etc). The user consent controls whether the PPAPI associated with that module can operate or 520 * not. If a module already has a user choice opt-in or opt-out, then only user choice unknown 521 * will be accepted as a hard reset option, after which the user choice should be set to the 522 * desired value as soon as possible. 523 * 524 * @param updateParams object containing user choices for modules. 525 * @param executor the executor for the callback. 526 * @param callback callback function to confirm module user choice is set up correctly. 527 * @hide 528 */ 529 @SystemApi 530 @FlaggedApi(Flags.FLAG_ADSERVICES_ENABLE_PER_MODULE_OVERRIDES_API) 531 @RequiresPermission(anyOf = {MODIFY_ADSERVICES_STATE, MODIFY_ADSERVICES_STATE_COMPAT}) 532 public void requestAdServicesModuleUserChoices( 533 @NonNull UpdateAdServicesUserChoicesParams updateParams, 534 @NonNull @CallbackExecutor Executor executor, 535 @NonNull AdServicesOutcomeReceiver<Void, Exception> callback) { 536 Objects.requireNonNull(updateParams, "updateParams cannot be null"); 537 Objects.requireNonNull(executor, "executor cannot be null"); 538 Objects.requireNonNull(callback, "callback cannot be null"); 539 540 if (invokeCallbackOnErrorOnRvc(callback)) { 541 return; 542 } 543 544 final IAdServicesCommonService service = getService(); 545 try { 546 service.requestAdServicesModuleUserChoices( 547 updateParams, 548 new IRequestAdServicesModuleUserChoicesCallback.Stub() { 549 @Override 550 public void onSuccess() throws RemoteException { 551 callback.onResult(null); 552 } 553 554 @Override 555 public void onFailure(int statusCode) throws RemoteException { 556 callback.onError( 557 new IllegalStateException( 558 "Internal Error! status code: " + statusCode)); 559 } 560 }); 561 } catch (RemoteException e) { 562 LogUtil.e(e, "RemoteException"); 563 executor.execute( 564 () -> callback.onError(new IllegalStateException("Internal Error!", e))); 565 } 566 } 567 568 /** 569 * Enable AdServices based on the AdServicesStates input parameter. This API is for Android R, 570 * and uses the AdServicesOutcomeReceiver class because OutcomeReceiver is not available. 571 * 572 * <p>Based on the provided {@code AdServicesStates}, AdServices may be enabled. Specifically, 573 * users will be provided with an enrollment channel (such as notification) to become privacy 574 * sandbox users when: 575 * 576 * <ul> 577 * <li>isAdServicesUiEnabled - true. 578 * <li>isU18Account | isAdultAccount - true. 579 * </ul> 580 * 581 * @param adServicesStates parcel containing relevant AdServices state variables. 582 * @deprecated use {@link #enableAdServices(AdServicesStates, Executor, OutcomeReceiver)} 583 * instead. Android R is no longer supported. 584 * @hide 585 */ 586 @SystemApi 587 @RequiresPermission(anyOf = {MODIFY_ADSERVICES_STATE, MODIFY_ADSERVICES_STATE_COMPAT}) 588 @Deprecated 589 @FlaggedApi(Flags.FLAG_ADSERVICES_OUTCOMERECEIVER_R_API_DEPRECATED) 590 @SuppressWarnings("NewApi") 591 public void enableAdServices( 592 @NonNull AdServicesStates adServicesStates, 593 @NonNull @CallbackExecutor Executor executor, 594 @NonNull AdServicesOutcomeReceiver<Boolean, Exception> callback) { 595 596 if (invokeCallbackOnErrorOnRvc(callback)) { 597 return; 598 } 599 600 enableAdServices( 601 adServicesStates, executor, OutcomeReceiverConverter.toOutcomeReceiver(callback)); 602 } 603 604 /** 605 * Updates {@link AdId} in Adservices when the device changes {@link AdId}. This API is used by 606 * AdIdProvider. 607 * 608 * @param updateAdIdRequest the request that contains {@link AdId} information to update. 609 * @param executor the executor for the callback. 610 * @param callback the callback in type {@link AdServicesOutcomeReceiver}, available on Android 611 * R and above. 612 * @throws IllegalStateException when service is not available or the feature is not enabled, or 613 * if there is any {@code Binder} invocation error. 614 * @throws SecurityException when the caller is not authorized to call this API. 615 * @deprecated use {@link #updateAdId(UpdateAdIdRequest, Executor, OutcomeReceiver)} instead. 616 * Android R is no longer supported. 617 * @hide 618 */ 619 // TODO(b/295205476): Move exceptions into the callback. 620 @SystemApi 621 @RequiresPermission(anyOf = {UPDATE_PRIVILEGED_AD_ID, UPDATE_PRIVILEGED_AD_ID_COMPAT}) 622 @Deprecated 623 @FlaggedApi(Flags.FLAG_ADSERVICES_OUTCOMERECEIVER_R_API_DEPRECATED) 624 @SuppressWarnings("NewApi") 625 public void updateAdId( 626 @NonNull UpdateAdIdRequest updateAdIdRequest, 627 @NonNull @CallbackExecutor Executor executor, 628 @NonNull AdServicesOutcomeReceiver<Boolean, Exception> callback) { 629 630 if (invokeCallbackOnErrorOnRvc(callback)) { 631 return; 632 } 633 634 updateAdId( 635 updateAdIdRequest, executor, OutcomeReceiverConverter.toOutcomeReceiver(callback)); 636 } 637 638 /** 639 * Updates {@link AdId} in Adservices when the device changes {@link AdId}. This API is used by 640 * AdIdProvider. 641 * 642 * @param updateAdIdRequest the request that contains {@link AdId} information to update. 643 * @param executor the executor for the callback. 644 * @param callback the callback in type {@link OutcomeReceiver}, available on Android S and 645 * above. 646 * @throws IllegalStateException when service is not available or the feature is not enabled, or 647 * if there is any {@code Binder} invocation error. 648 * @throws SecurityException when the caller is not authorized to call this API. 649 * @hide 650 */ 651 @SystemApi 652 @RequiresPermission(anyOf = {UPDATE_PRIVILEGED_AD_ID, UPDATE_PRIVILEGED_AD_ID_COMPAT}) 653 @RequiresApi(Build.VERSION_CODES.S) 654 public void updateAdId( 655 @NonNull UpdateAdIdRequest updateAdIdRequest, 656 @NonNull @CallbackExecutor Executor executor, 657 @NonNull OutcomeReceiver<Boolean, Exception> callback) { 658 Objects.requireNonNull(updateAdIdRequest); 659 Objects.requireNonNull(executor); 660 Objects.requireNonNull(callback); 661 662 IAdServicesCommonService service = getService(); 663 try { 664 service.updateAdIdCache( 665 updateAdIdRequest, 666 new IUpdateAdIdCallback.Stub() { 667 @Override 668 public void onResult(String message) { 669 executor.execute(() -> callback.onResult(true)); 670 } 671 672 @Override 673 public void onFailure(int statusCode) { 674 executor.execute( 675 () -> 676 callback.onError( 677 AdServicesStatusUtils.asException(statusCode))); 678 } 679 }); 680 } catch (RemoteException e) { 681 LogUtil.e(e, "RemoteException calling updateAdIdCache with %s", updateAdIdRequest); 682 executor.execute( 683 () -> callback.onError(new IllegalStateException("Internal Error!", e))); 684 } 685 } 686 687 /** 688 * Get the AdService's common states. 689 * 690 * @param executor the executor for the callback. 691 * @param callback the callback in type {@link AdServicesOutcomeReceiver}, available on Android 692 * R and above. 693 * @throws IllegalStateException if there is any {@code Binder} invocation error. 694 * @hide 695 */ 696 @SystemApi 697 @FlaggedApi(Flags.FLAG_GET_ADSERVICES_COMMON_STATES_API_ENABLED) 698 @RequiresPermission(anyOf = {ACCESS_ADSERVICES_STATE, ACCESS_ADSERVICES_STATE_COMPAT}) 699 public void getAdservicesCommonStates( 700 @NonNull @CallbackExecutor Executor executor, 701 @NonNull 702 AdServicesOutcomeReceiver<AdServicesCommonStatesResponse, Exception> callback) { 703 704 if (invokeCallbackOnErrorOnRvc(callback)) { 705 return; 706 } 707 708 final IAdServicesCommonService service = getService(); 709 CallerMetadata callerMetadata = 710 new CallerMetadata.Builder() 711 .setBinderElapsedTimestamp(SystemClock.elapsedRealtime()) 712 .build(); 713 String appPackageName = ""; 714 String sdkPackageName = ""; 715 // First check if context is SandboxedSdkContext or not 716 SandboxedSdkContext sandboxedSdkContext = 717 SandboxedSdkContextUtils.getAsSandboxedSdkContext(mContext); 718 if (sandboxedSdkContext != null) { 719 // This is the case with the Sandbox. 720 sdkPackageName = sandboxedSdkContext.getSdkPackageName(); 721 appPackageName = sandboxedSdkContext.getClientPackageName(); 722 } else { 723 // This is the case without the Sandbox. 724 appPackageName = mContext.getPackageName(); 725 } 726 try { 727 service.getAdServicesCommonStates( 728 new GetAdServicesCommonStatesParams.Builder(appPackageName, sdkPackageName) 729 .build(), 730 callerMetadata, 731 new IAdServicesCommonStatesCallback.Stub() { 732 @Override 733 public void onResult(AdServicesCommonStatesResponse result) { 734 executor.execute( 735 () -> { 736 callback.onResult(result); 737 }); 738 } 739 740 @Override 741 public void onFailure(int statusCode) { 742 executor.execute( 743 () -> 744 callback.onError( 745 AdServicesStatusUtils.asException(statusCode))); 746 } 747 }); 748 } catch (RemoteException e) { 749 LogUtil.e(e, "RemoteException"); 750 executor.execute( 751 () -> callback.onError(new IllegalStateException("Internal Error!", e))); 752 } 753 } 754 } 755