308 lines
10 KiB
Java
308 lines
10 KiB
Java
/*
|
|
* Copyright (C) 2022 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package android.adservices.common;
|
|
|
|
import android.annotation.NonNull;
|
|
import android.annotation.Nullable;
|
|
import android.net.Uri;
|
|
import android.os.Parcel;
|
|
import android.os.Parcelable;
|
|
|
|
import com.android.adservices.AdServicesParcelableUtil;
|
|
import com.android.internal.util.Preconditions;
|
|
|
|
import java.util.HashSet;
|
|
import java.util.Objects;
|
|
import java.util.Set;
|
|
|
|
/** Represents data specific to an ad that is necessary for ad selection and rendering. */
|
|
public final class AdData implements Parcelable {
|
|
/** @hide */
|
|
public static final String NUM_AD_COUNTER_KEYS_EXCEEDED_FORMAT =
|
|
"AdData should have no more than %d ad counter keys";
|
|
/** @hide */
|
|
public static final int MAX_NUM_AD_COUNTER_KEYS = 10;
|
|
|
|
@NonNull private final Uri mRenderUri;
|
|
@NonNull private final String mMetadata;
|
|
@NonNull private final Set<Integer> mAdCounterKeys;
|
|
@Nullable private final AdFilters mAdFilters;
|
|
@Nullable private final String mAdRenderId;
|
|
|
|
@NonNull
|
|
public static final Creator<AdData> CREATOR =
|
|
new Creator<AdData>() {
|
|
@Override
|
|
public AdData createFromParcel(@NonNull Parcel in) {
|
|
Objects.requireNonNull(in);
|
|
|
|
return new AdData(in);
|
|
}
|
|
|
|
@Override
|
|
public AdData[] newArray(int size) {
|
|
return new AdData[size];
|
|
}
|
|
};
|
|
|
|
private AdData(@NonNull AdData.Builder builder) {
|
|
Objects.requireNonNull(builder);
|
|
|
|
mRenderUri = builder.mRenderUri;
|
|
mMetadata = builder.mMetadata;
|
|
mAdCounterKeys = builder.mAdCounterKeys;
|
|
mAdFilters = builder.mAdFilters;
|
|
mAdRenderId = builder.mAdRenderId;
|
|
}
|
|
|
|
private AdData(@NonNull Parcel in) {
|
|
Objects.requireNonNull(in);
|
|
|
|
mRenderUri = Uri.CREATOR.createFromParcel(in);
|
|
mMetadata = in.readString();
|
|
mAdCounterKeys =
|
|
AdServicesParcelableUtil.readNullableFromParcel(
|
|
in, AdServicesParcelableUtil::readIntegerSetFromParcel);
|
|
mAdFilters =
|
|
AdServicesParcelableUtil.readNullableFromParcel(
|
|
in, AdFilters.CREATOR::createFromParcel);
|
|
mAdRenderId = in.readString();
|
|
}
|
|
|
|
@Override
|
|
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
|
Objects.requireNonNull(dest);
|
|
|
|
mRenderUri.writeToParcel(dest, flags);
|
|
dest.writeString(mMetadata);
|
|
AdServicesParcelableUtil.writeNullableToParcel(
|
|
dest, mAdCounterKeys, AdServicesParcelableUtil::writeIntegerSetToParcel);
|
|
AdServicesParcelableUtil.writeNullableToParcel(
|
|
dest,
|
|
mAdFilters,
|
|
(targetParcel, sourceFilters) -> sourceFilters.writeToParcel(targetParcel, flags));
|
|
dest.writeString(mAdRenderId);
|
|
}
|
|
|
|
/** @hide */
|
|
@Override
|
|
public int describeContents() {
|
|
return 0;
|
|
}
|
|
|
|
/** Gets the URI that points to the ad's rendering assets. The URI must use HTTPS. */
|
|
@NonNull
|
|
public Uri getRenderUri() {
|
|
return mRenderUri;
|
|
}
|
|
|
|
/**
|
|
* Gets the buyer ad metadata used during the ad selection process.
|
|
*
|
|
* <p>The metadata should be a valid JSON object serialized as a string. Metadata represents
|
|
* ad-specific bidding information that will be used during ad selection as part of bid
|
|
* generation and used in buyer JavaScript logic, which is executed in an isolated execution
|
|
* environment.
|
|
*
|
|
* <p>If the metadata is not a valid JSON object that can be consumed by the buyer's JS, the ad
|
|
* will not be eligible for ad selection.
|
|
*/
|
|
@NonNull
|
|
public String getMetadata() {
|
|
return mMetadata;
|
|
}
|
|
|
|
/**
|
|
* Gets the set of keys used in counting events.
|
|
*
|
|
* <p>No more than 10 ad counter keys may be associated with an ad.
|
|
*
|
|
* <p>The keys and counts per key are used in frequency cap filtering during ad selection to
|
|
* disqualify associated ads from being submitted to bidding.
|
|
*
|
|
* <p>Note that these keys can be overwritten along with the ads and other bidding data for a
|
|
* custom audience during the custom audience's daily update.
|
|
*/
|
|
@NonNull
|
|
public Set<Integer> getAdCounterKeys() {
|
|
return mAdCounterKeys;
|
|
}
|
|
|
|
/**
|
|
* Gets all {@link AdFilters} associated with the ad.
|
|
*
|
|
* <p>The filters, if met or exceeded, exclude the associated ad from participating in ad
|
|
* selection. They are optional and if {@code null} specify that no filters apply to this ad.
|
|
*/
|
|
@Nullable
|
|
public AdFilters getAdFilters() {
|
|
return mAdFilters;
|
|
}
|
|
|
|
/**
|
|
* Gets the ad render id for server auctions.
|
|
*
|
|
* <p>Ad render id is collected for each {@link AdData} when server auction request is received.
|
|
*
|
|
* <p>Any {@link AdData} without ad render id will be ineligible for server-side auction.
|
|
*
|
|
* <p>The overall size of the CA is limited. The size of this field is considered using
|
|
* {@link String#getBytes()} in {@code UTF-8} encoding.
|
|
*/
|
|
@Nullable
|
|
public String getAdRenderId() {
|
|
return mAdRenderId;
|
|
}
|
|
|
|
/** Checks whether two {@link AdData} objects contain the same information. */
|
|
@Override
|
|
public boolean equals(Object o) {
|
|
if (this == o) return true;
|
|
if (!(o instanceof AdData)) return false;
|
|
AdData adData = (AdData) o;
|
|
return mRenderUri.equals(adData.mRenderUri)
|
|
&& mMetadata.equals(adData.mMetadata)
|
|
&& mAdCounterKeys.equals(adData.mAdCounterKeys)
|
|
&& Objects.equals(mAdFilters, adData.mAdFilters)
|
|
&& Objects.equals(mAdRenderId, adData.mAdRenderId);
|
|
}
|
|
|
|
/** Returns the hash of the {@link AdData} object's data. */
|
|
@Override
|
|
public int hashCode() {
|
|
return Objects.hash(mRenderUri, mMetadata, mAdCounterKeys, mAdFilters);
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "AdData{"
|
|
+ "mRenderUri="
|
|
+ mRenderUri
|
|
+ ", mMetadata='"
|
|
+ mMetadata
|
|
+ '\''
|
|
+ ", mAdCounterKeys="
|
|
+ mAdCounterKeys
|
|
+ ", mAdFilters="
|
|
+ mAdFilters
|
|
+ ", mAdRenderId='"
|
|
+ mAdRenderId
|
|
+ '\''
|
|
+ '}';
|
|
}
|
|
|
|
/** Builder for {@link AdData} objects. */
|
|
public static final class Builder {
|
|
@Nullable private Uri mRenderUri;
|
|
@Nullable private String mMetadata;
|
|
@NonNull private Set<Integer> mAdCounterKeys = new HashSet<>();
|
|
@Nullable private AdFilters mAdFilters;
|
|
@Nullable private String mAdRenderId;
|
|
|
|
// TODO(b/232883403): We may need to add @NonNUll members as args.
|
|
public Builder() {}
|
|
|
|
/**
|
|
* Sets the URI that points to the ad's rendering assets. The URI must use HTTPS.
|
|
*
|
|
* <p>See {@link #getRenderUri()} for detail.
|
|
*/
|
|
@NonNull
|
|
public AdData.Builder setRenderUri(@NonNull Uri renderUri) {
|
|
Objects.requireNonNull(renderUri);
|
|
mRenderUri = renderUri;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets the buyer ad metadata used during the ad selection process.
|
|
*
|
|
* <p>The metadata should be a valid JSON object serialized as a string. Metadata represents
|
|
* ad-specific bidding information that will be used during ad selection as part of bid
|
|
* generation and used in buyer JavaScript logic, which is executed in an isolated execution
|
|
* environment.
|
|
*
|
|
* <p>If the metadata is not a valid JSON object that can be consumed by the buyer's JS, the
|
|
* ad will not be eligible for ad selection.
|
|
*
|
|
* <p>See {@link #getMetadata()} for detail.
|
|
*/
|
|
@NonNull
|
|
public AdData.Builder setMetadata(@NonNull String metadata) {
|
|
Objects.requireNonNull(metadata);
|
|
mMetadata = metadata;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets the set of keys used in counting events.
|
|
*
|
|
* <p>No more than 10 ad counter keys may be associated with an ad.
|
|
*
|
|
* <p>See {@link #getAdCounterKeys()} for more information.
|
|
*/
|
|
@NonNull
|
|
public AdData.Builder setAdCounterKeys(@NonNull Set<Integer> adCounterKeys) {
|
|
Objects.requireNonNull(adCounterKeys);
|
|
Preconditions.checkArgument(
|
|
!adCounterKeys.contains(null), "Ad counter keys must not contain null value");
|
|
Preconditions.checkArgument(
|
|
adCounterKeys.size() <= MAX_NUM_AD_COUNTER_KEYS,
|
|
NUM_AD_COUNTER_KEYS_EXCEEDED_FORMAT,
|
|
MAX_NUM_AD_COUNTER_KEYS);
|
|
mAdCounterKeys = adCounterKeys;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets all {@link AdFilters} associated with the ad.
|
|
*
|
|
* <p>See {@link #getAdFilters()} for more information.
|
|
*/
|
|
@NonNull
|
|
public AdData.Builder setAdFilters(@Nullable AdFilters adFilters) {
|
|
mAdFilters = adFilters;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets the ad render id for server auction
|
|
*
|
|
* <p>See {@link AdData#getAdRenderId()} for more information.
|
|
*/
|
|
@NonNull
|
|
public AdData.Builder setAdRenderId(@Nullable String adRenderId) {
|
|
mAdRenderId = adRenderId;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Builds the {@link AdData} object.
|
|
*
|
|
* @throws NullPointerException if any required parameters are {@code null} when built
|
|
*/
|
|
@NonNull
|
|
public AdData build() {
|
|
Objects.requireNonNull(mRenderUri, "The render URI has not been provided");
|
|
// TODO(b/231997523): Add JSON field validation.
|
|
Objects.requireNonNull(mMetadata, "The metadata has not been provided");
|
|
|
|
return new AdData(this);
|
|
}
|
|
}
|
|
}
|