# CustomAudienceManagerFutures

Artifact: [androidx.privacysandbox.ads:ads-adservices-java](https://developer.android.com/jetpack/androidx/releases/privacysandbox-ads) [View Source](https://cs.android.com/search?q=file:androidx/privacysandbox/ads/adservices/java/customaudience/CustomAudienceManagerFutures.kt+class:androidx.privacysandbox.ads.adservices.java.customaudience.CustomAudienceManagerFutures) Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/privacysandbox-ads#1.0.0)

*** ** * ** ***

<br />

```
public abstract class CustomAudienceManagerFutures
```

<br />

*** ** * ** ***

This class provides APIs for app and ad-SDKs to join / leave custom audiences. This class can be used by Java clients.

## Summary

| ### Public methods |
|---|---|
| `abstract @https://developer.android.com/reference/androidx/annotation/NonNull https://guava.dev/releases/snapshot-android/api/docs/com/google/common/util/concurrent/ListenableFuture.html<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html>` | `@https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/common/ExperimentalFeatures.Ext10OptIn @https://developer.android.com/reference/androidx/annotation/RequiresPermission(value = "android.permission.ACCESS_ADSERVICES_CUSTOM_AUDIENCE") https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/java/customaudience/CustomAudienceManagerFutures#fetchAndJoinCustomAudienceAsync(androidx.privacysandbox.ads.adservices.customaudience.FetchAndJoinCustomAudienceRequest)( @https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/customaudience/FetchAndJoinCustomAudienceRequest request )` Adds the user to the `https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/customaudience/CustomAudience` fetched from a {@code fetchUri}. |
| `static final https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/java/customaudience/CustomAudienceManagerFutures` | `https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/java/customaudience/CustomAudienceManagerFutures#from(android.content.Context)(@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/android/content/Context.html context)` Creates `https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/java/customaudience/CustomAudienceManagerFutures`. |
| `abstract @https://developer.android.com/reference/androidx/annotation/NonNull https://guava.dev/releases/snapshot-android/api/docs/com/google/common/util/concurrent/ListenableFuture.html<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html>` | `@https://developer.android.com/reference/androidx/annotation/RequiresPermission(value = "android.permission.ACCESS_ADSERVICES_CUSTOM_AUDIENCE") https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/java/customaudience/CustomAudienceManagerFutures#joinCustomAudienceAsync(androidx.privacysandbox.ads.adservices.customaudience.JoinCustomAudienceRequest)(@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/customaudience/JoinCustomAudienceRequest request)` Adds the user to the given `https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/customaudience/CustomAudience`. |
| `abstract @https://developer.android.com/reference/androidx/annotation/NonNull https://guava.dev/releases/snapshot-android/api/docs/com/google/common/util/concurrent/ListenableFuture.html<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html>` | `@https://developer.android.com/reference/androidx/annotation/RequiresPermission(value = "android.permission.ACCESS_ADSERVICES_CUSTOM_AUDIENCE") https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/java/customaudience/CustomAudienceManagerFutures#leaveCustomAudienceAsync(androidx.privacysandbox.ads.adservices.customaudience.LeaveCustomAudienceRequest)(@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/customaudience/LeaveCustomAudienceRequest request)` Attempts to remove a user from a custom audience by deleting any existing `https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/customaudience/CustomAudience` data, identified by {@code ownerPackageName}, {@code buyer}, and {@code name}. |
| `abstract @https://developer.android.com/reference/androidx/annotation/NonNull https://guava.dev/releases/snapshot-android/api/docs/com/google/common/util/concurrent/ListenableFuture.html<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html>` | `@https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/common/ExperimentalFeatures.Ext14OptIn @https://developer.android.com/reference/androidx/annotation/RequiresPermission(value = "android.permission.ACCESS_ADSERVICES_CUSTOM_AUDIENCE") https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/java/customaudience/CustomAudienceManagerFutures#scheduleCustomAudienceUpdateAsync(androidx.privacysandbox.ads.adservices.customaudience.ScheduleCustomAudienceUpdateRequest)( @https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/customaudience/ScheduleCustomAudienceUpdateRequest request )` Allows the API caller to schedule a deferred Custom Audience update. |

## Public methods

### fetchAndJoinCustomAudienceAsync

Added in [1.1.0-beta12](https://developer.android.com/jetpack/androidx/releases/privacysandbox-ads#1.1.0-beta12)

```
@ExperimentalFeatures.Ext10OptIn
@RequiresPermission(value = "android.permission.ACCESS_ADSERVICES_CUSTOM_AUDIENCE")
public abstract @NonNull ListenableFuture<Unit> fetchAndJoinCustomAudienceAsync(
    @NonNull FetchAndJoinCustomAudienceRequest request
)
```

Adds the user to the `https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/customaudience/CustomAudience` fetched from a {@code fetchUri}.

An attempt to register the user for a custom audience with the same combination of {@code ownerPackageName}, {@code buyer}, and {@code name} will cause the existing custom audience's information to be overwritten, including the list of ads data.

Note that the ads list can be completely overwritten by the daily background fetch job.

This call fails with an `https://developer.android.com/reference/java/lang/SecurityException.html` if

1. the {@code ownerPackageName} is not calling app's package name and/or
2. the buyer is not authorized to use the API.

This call fails with an `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-illegal-argument-exception/index.html` if

1. the storage limit has been exceeded by the calling application and/or
2. any URI parameters in the \[CustomAudience\] given are not authenticated with the \[CustomAudience\] buyer.

This call fails with `https://developer.android.com/reference/android/os/LimitExceededException.html` if the calling package exceeds the allowed rate limits and is throttled.

This call fails with an `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-illegal-state-exception/index.html` if an internal service error is encountered.

This call fails with an `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unsupported-operation-exception/index.html` if the Android API level and AdServices module versions don't support this API.

| Parameters |
|---|---|
| `@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/customaudience/FetchAndJoinCustomAudienceRequest request` | The request to fetch and join custom audience. |

### from

Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/privacysandbox-ads#1.0.0)

```
public static final CustomAudienceManagerFutures from(@NonNull Context context)
```

Creates `https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/java/customaudience/CustomAudienceManagerFutures`.

| Returns |
|---|---|
| `https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/java/customaudience/CustomAudienceManagerFutures` | CustomAudienceManagerFutures object. If the device is running an incompatible build, the value returned is null. |

### joinCustomAudienceAsync

Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/privacysandbox-ads#1.0.0)

```
@RequiresPermission(value = "android.permission.ACCESS_ADSERVICES_CUSTOM_AUDIENCE")
public abstract @NonNull ListenableFuture<Unit> joinCustomAudienceAsync(@NonNull JoinCustomAudienceRequest request)
```

Adds the user to the given `https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/customaudience/CustomAudience`.

An attempt to register the user for a custom audience with the same combination of {@code ownerPackageName}, {@code buyer}, and {@code name} will cause the existing custom audience's information to be overwritten, including the list of ads data.

Note that the ads list can be completely overwritten by the daily background fetch job.

This call fails with an `https://developer.android.com/reference/java/lang/SecurityException.html` if

1. the {@code ownerPackageName} is not calling app's package name and/or
2. the buyer is not authorized to use the API.

This call fails with an `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-illegal-argument-exception/index.html` if

1. the storage limit has been exceeded by the calling application and/or
2. any URI parameters in the \[CustomAudience\] given are not authenticated with the \[CustomAudience\] buyer.

This call fails with `https://developer.android.com/reference/android/os/LimitExceededException.html` if the calling package exceeds the allowed rate limits and is throttled.

This call fails with an `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-illegal-state-exception/index.html` if an internal service error is encountered.

| Parameters |
|---|---|
| `@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/customaudience/JoinCustomAudienceRequest request` | The request to join custom audience. |

### leaveCustomAudienceAsync

Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/privacysandbox-ads#1.0.0)

```
@RequiresPermission(value = "android.permission.ACCESS_ADSERVICES_CUSTOM_AUDIENCE")
public abstract @NonNull ListenableFuture<Unit> leaveCustomAudienceAsync(@NonNull LeaveCustomAudienceRequest request)
```

Attempts to remove a user from a custom audience by deleting any existing `https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/customaudience/CustomAudience` data, identified by {@code ownerPackageName}, {@code buyer}, and {@code name}.

This call fails with an `https://developer.android.com/reference/java/lang/SecurityException.html` if

1. the {@code ownerPackageName} is not calling app's package name; and/or
2. the buyer is not authorized to use the API.

This call fails with `https://developer.android.com/reference/android/os/LimitExceededException.html` if the calling package exceeds the allowed rate limits and is throttled.

This call does not inform the caller whether the custom audience specified existed in on-device storage. In other words, it will fail silently when a buyer attempts to leave a custom audience that was not joined.

| Parameters |
|---|---|
| `@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/customaudience/LeaveCustomAudienceRequest request` | The request to leave custom audience. |

### scheduleCustomAudienceUpdateAsync

Added in [1.1.0-beta12](https://developer.android.com/jetpack/androidx/releases/privacysandbox-ads#1.1.0-beta12)

```
@ExperimentalFeatures.Ext14OptIn
@RequiresPermission(value = "android.permission.ACCESS_ADSERVICES_CUSTOM_AUDIENCE")
public abstract @NonNull ListenableFuture<Unit> scheduleCustomAudienceUpdateAsync(
    @NonNull ScheduleCustomAudienceUpdateRequest request
)
```

Allows the API caller to schedule a deferred Custom Audience update. For each update the user will be able to join/leave a set of Custom Audiences or schedule a deferred Custom Audience update.

The API only guarantees a minimum delay before initiating the update. It does not guarantee a maximum deadline for the update, nor does it guarantee that the update will occur at all, as requests older than one day are removed. Scheduled updates could be batched and queued together to preserve system resources, thus exact delay time is not guaranteed.

In order to conserve system resources the API will make an update request only if the following constraints are satisfied:

- The device battery is not low

- The device storage is not low

When the deferred update is triggered, the API makes a POST request to the provided `updateUri`. The request body contains a JSON representation of the Partial Custom Audience list if provided by the caller.

An example of request body when the API calls the `updateUri` containing list of Partial Custom Audiences would look like:

```java
{
    "partial_custom_audience_data": [
        {
            "name": "running_shoes",
            "activation_time": 1644375856883,
            "expiration_time": 1644375908397
        },
        {
            "name": "casual_shirt",
            "user_bidding_signals": {"signal1": "value"}
        }
    ]
}
```

In response, the API expects a JSON in response with either join/leave or schedule:

- `join` and/or `leave` :

  - `join` : Should contain list containing full data for a `https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/customaudience/CustomAudience` object

  - `leave` : List of `https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/customaudience/CustomAudience` names that user is intended to be removed from

An example of JSON in response with `join/leave` would look like:

```java
{
    "join": [
        {
            "name": "running-shoes",
            "activation_time": 1644375856883,
            "expiration_time": 1644375908397,
            "user_bidding_signals": {"signal1": "value"},
            "trusted_bidding_data": {
                "trusted_bidding_uri": "https://example-dsp.com/...",
                "trusted_bidding_keys": ["k1", "k2"]
            },
            "bidding_logic_uri": "https://example-dsp.com/...",
            "ads": [
                {
                    "render_uri": "https://example-dsp.com/...",
                    "metadata": {},
                    "ad_filters": {
                        "frequency_cap": {
                            "win": [
                                {
                                    "ad_counter_key": "key1",
                                    "max_count": 2,
                                    "interval_in_seconds": 60
                                }
                            ],
                            "view": [
                                {
                                    "ad_counter_key": "key2",
                                    "max_count": 10,
                                    "interval_in_seconds": 3600
                                }
                            ]
                        },
                        "app_install": {
                            "package_names": ["package.name.one"]
                        }
                    }
                }
            ]
        }
    ],
    "leave": ["tennis_shoes", "formal_shirt"]
}
```

- `schedule` : List of deferred Custom Audience update requests that the MMP intends to schedule for one or more DSPs

An example of JSON in response with `schedule` would look like:

```java
{
  "schedule": {
    "requests": [
      {
        "update_uri": "https://example-dsp.com/...",
        "min_delay": "30",
        "should_replace_pending_updates": true,
        "partial_custom_audience_data": [
          {
            "name": "running-shoes",
            "activation_time": 1644375856883,
            "expiration_time": 1644375908397
          },
          {
            "name": "casual_shirt",
            "user_bidding_signals": {
              "signal1": "value"
            }
          }
        ],
        "leave": [
          "tennis_shoes",
          "formal_shirt"
        ]
      }
    ]
  }
}
```

An example of request body when the API calls the `updateUri` provided by the above schedule request would look like:

```java
{
    "partial_custom_audience_data": [
        {
            "name": "running_shoes",
            "activation_time": 1644375856883,
            "expiration_time": 1644375908397
        },
        {
            "name": "casual_shirt",
            "user_bidding_signals": {"signal1": "value"}
        }
    ],
    "leave": ["tennis_shoes", "formal_shirt"]
}
```

An example of the JSON response from calling the `updateUri` would look the same as the JSON response containing `join` and `leave` keys above.

An attempt to register a user for a custom audience with the same `owner` (calling app), `buyer` (inferred from `updateUri`) and `name` combination, the existing custom audience's information will be overwritten, including the list of ads data.

If information related to any `https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/customaudience/CustomAudience` to be joined is malformed, the deferred update will silently ignore that `https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/customaudience/CustomAudience`. Similarly, if a scheduled request is malformed, the scheduled update will silently ignore it.

When removing a user from a `https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/customaudience/CustomAudience`, this API deletes the existing `https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/customaudience/CustomAudience` identified by the `owner` (calling app), `buyer` (inferred from the `updateUri`), and `name`.

Any partial custom audience field set by the caller cannot be overridden by the `https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/customaudience/CustomAudience` fetched from the `updateUri`. Given that multiple Custom Audiences could be returned by a DSP, we will match the override restriction based on the names of the Custom Audiences. A DSP may skip returning a full Custom Audience for any Partial Custom Audience in the request.

In case the API encounters transient errors while making the network call for update, like 5xx, connection timeout, rate limit exceeded, it would defer the update to the next job.

This call fails with an `https://developer.android.com/reference/java/lang/SecurityException.html` if

1. the `ownerPackageName` is not calling app's package name; and/or

2. the buyer, inferred from `updateUri`, is not authorized to use the API.

This call fails with an `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-illegal-argument-exception/index.html` if

1. the provided `updateUri` is invalid or malformed.

2. the provided `delayTime` is not within permissible bounds

3. the combined size of `https://developer.android.com/reference/androidx/privacysandbox/ads/adservices/customaudience/PartialCustomAudience` list is larger than allowed limits

This call fails with `https://developer.android.com/reference/android/os/LimitExceededException.html` if the calling package exceeds the allowed rate limits and is throttled.