• 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 package android.adservices.adselection;
17 
18 import android.adservices.common.AdSelectionSignals;
19 import android.adservices.common.AdTechIdentifier;
20 import android.annotation.NonNull;
21 import android.net.Uri;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 
25 import com.android.adservices.AdServicesParcelableUtil;
26 
27 import java.util.Collections;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Objects;
31 
32 /**
33  * Contains the configuration of the ad selection process.
34  *
35  * <p>Instances of this class are created by SDKs to be provided as arguments to the {@link
36  * AdSelectionManager#selectAds} and {@link AdSelectionManager#reportImpression} methods in {@link
37  * AdSelectionManager}.
38  */
39 // TODO(b/233280314): investigate on adSelectionConfig optimization by merging mCustomAudienceBuyers
40 //  and mPerBuyerSignals.
41 public final class AdSelectionConfig implements Parcelable {
42     @NonNull private final AdTechIdentifier mSeller;
43     @NonNull private final Uri mDecisionLogicUri;
44     @NonNull private final List<AdTechIdentifier> mCustomAudienceBuyers;
45     @NonNull private final AdSelectionSignals mAdSelectionSignals;
46     @NonNull private final AdSelectionSignals mSellerSignals;
47     @NonNull private final Map<AdTechIdentifier, AdSelectionSignals> mPerBuyerSignals;
48     @NonNull private final Map<AdTechIdentifier, ContextualAds> mBuyerContextualAds;
49     @NonNull private final Uri mTrustedScoringSignalsUri;
50 
51     @NonNull
52     public static final Creator<AdSelectionConfig> CREATOR =
53             new Creator<AdSelectionConfig>() {
54                 @Override
55                 public AdSelectionConfig createFromParcel(@NonNull Parcel in) {
56                     Objects.requireNonNull(in);
57                     return new AdSelectionConfig(in);
58                 }
59 
60                 @Override
61                 public AdSelectionConfig[] newArray(int size) {
62                     return new AdSelectionConfig[size];
63                 }
64             };
65 
AdSelectionConfig( @onNull AdTechIdentifier seller, @NonNull Uri decisionLogicUri, @NonNull List<AdTechIdentifier> customAudienceBuyers, @NonNull AdSelectionSignals adSelectionSignals, @NonNull AdSelectionSignals sellerSignals, @NonNull Map<AdTechIdentifier, AdSelectionSignals> perBuyerSignals, @NonNull Map<AdTechIdentifier, ContextualAds> perBuyerContextualAds, @NonNull Uri trustedScoringSignalsUri)66     private AdSelectionConfig(
67             @NonNull AdTechIdentifier seller,
68             @NonNull Uri decisionLogicUri,
69             @NonNull List<AdTechIdentifier> customAudienceBuyers,
70             @NonNull AdSelectionSignals adSelectionSignals,
71             @NonNull AdSelectionSignals sellerSignals,
72             @NonNull Map<AdTechIdentifier, AdSelectionSignals> perBuyerSignals,
73             @NonNull Map<AdTechIdentifier, ContextualAds> perBuyerContextualAds,
74             @NonNull Uri trustedScoringSignalsUri) {
75         this.mSeller = seller;
76         this.mDecisionLogicUri = decisionLogicUri;
77         this.mCustomAudienceBuyers = customAudienceBuyers;
78         this.mAdSelectionSignals = adSelectionSignals;
79         this.mSellerSignals = sellerSignals;
80         this.mPerBuyerSignals = perBuyerSignals;
81         this.mBuyerContextualAds = perBuyerContextualAds;
82         this.mTrustedScoringSignalsUri = trustedScoringSignalsUri;
83     }
84 
AdSelectionConfig(@onNull Parcel in)85     private AdSelectionConfig(@NonNull Parcel in) {
86         Objects.requireNonNull(in);
87         mSeller = AdTechIdentifier.CREATOR.createFromParcel(in);
88         mDecisionLogicUri = Uri.CREATOR.createFromParcel(in);
89         mCustomAudienceBuyers = in.createTypedArrayList(AdTechIdentifier.CREATOR);
90         mAdSelectionSignals = AdSelectionSignals.CREATOR.createFromParcel(in);
91         mSellerSignals = AdSelectionSignals.CREATOR.createFromParcel(in);
92         mPerBuyerSignals =
93                 AdServicesParcelableUtil.readMapFromParcel(
94                         in, AdTechIdentifier::fromString, AdSelectionSignals.class);
95         mBuyerContextualAds =
96                 AdServicesParcelableUtil.readMapFromParcel(
97                         in, AdTechIdentifier::fromString, ContextualAds.class);
98         mTrustedScoringSignalsUri = Uri.CREATOR.createFromParcel(in);
99     }
100 
101     @Override
describeContents()102     public int describeContents() {
103         return 0;
104     }
105 
106     @Override
writeToParcel(@onNull Parcel dest, int flags)107     public void writeToParcel(@NonNull Parcel dest, int flags) {
108         Objects.requireNonNull(dest);
109 
110         mSeller.writeToParcel(dest, flags);
111         mDecisionLogicUri.writeToParcel(dest, flags);
112         dest.writeTypedList(mCustomAudienceBuyers);
113         mAdSelectionSignals.writeToParcel(dest, flags);
114         mSellerSignals.writeToParcel(dest, flags);
115         AdServicesParcelableUtil.writeMapToParcel(dest, mPerBuyerSignals);
116         AdServicesParcelableUtil.writeMapToParcel(dest, mBuyerContextualAds);
117         mTrustedScoringSignalsUri.writeToParcel(dest, flags);
118     }
119 
120     @Override
equals(Object o)121     public boolean equals(Object o) {
122         if (this == o) return true;
123         if (!(o instanceof AdSelectionConfig)) return false;
124         AdSelectionConfig that = (AdSelectionConfig) o;
125         return Objects.equals(mSeller, that.mSeller)
126                 && Objects.equals(mDecisionLogicUri, that.mDecisionLogicUri)
127                 && Objects.equals(mCustomAudienceBuyers, that.mCustomAudienceBuyers)
128                 && Objects.equals(mAdSelectionSignals, that.mAdSelectionSignals)
129                 && Objects.equals(mSellerSignals, that.mSellerSignals)
130                 && Objects.equals(mPerBuyerSignals, that.mPerBuyerSignals)
131                 && Objects.equals(mBuyerContextualAds, that.mBuyerContextualAds)
132                 && Objects.equals(mTrustedScoringSignalsUri, that.mTrustedScoringSignalsUri);
133     }
134 
135     @Override
hashCode()136     public int hashCode() {
137         return Objects.hash(
138                 mSeller,
139                 mDecisionLogicUri,
140                 mCustomAudienceBuyers,
141                 mAdSelectionSignals,
142                 mSellerSignals,
143                 mPerBuyerSignals,
144                 mBuyerContextualAds,
145                 mTrustedScoringSignalsUri);
146     }
147 
148     /**
149      * @return a new builder instance created from this object's cloned data
150      * @hide
151      */
152     @NonNull
cloneToBuilder()153     public AdSelectionConfig.Builder cloneToBuilder() {
154         return new AdSelectionConfig.Builder()
155                 .setSeller(this.getSeller())
156                 .setBuyerContextualAds(this.getBuyerContextualAds())
157                 .setAdSelectionSignals(this.getAdSelectionSignals())
158                 .setCustomAudienceBuyers(this.getCustomAudienceBuyers())
159                 .setDecisionLogicUri(this.getDecisionLogicUri())
160                 .setPerBuyerSignals(this.getPerBuyerSignals())
161                 .setSellerSignals(this.getSellerSignals())
162                 .setTrustedScoringSignalsUri(this.getTrustedScoringSignalsUri());
163     }
164 
165     /** @return a AdTechIdentifier of the seller, for example "www.example-ssp.com" */
166     @NonNull
getSeller()167     public AdTechIdentifier getSeller() {
168         return mSeller;
169     }
170 
171     /**
172      * @return the URI used to retrieve the JS code containing the seller/SSP scoreAd function used
173      *     during the ad selection and reporting processes
174      */
175     @NonNull
getDecisionLogicUri()176     public Uri getDecisionLogicUri() {
177         return mDecisionLogicUri;
178     }
179 
180     /**
181      * @return a list of custom audience buyers allowed by the SSP to participate in the ad
182      *     selection process
183      */
184     @NonNull
getCustomAudienceBuyers()185     public List<AdTechIdentifier> getCustomAudienceBuyers() {
186         return mCustomAudienceBuyers;
187     }
188 
189     /**
190      * @return JSON in an AdSelectionSignals object, fetched from the AdSelectionConfig and consumed
191      *     by the JS logic fetched from the DSP, represents signals given to the participating
192      *     buyers in the ad selection and reporting processes.
193      */
194     @NonNull
getAdSelectionSignals()195     public AdSelectionSignals getAdSelectionSignals() {
196         return mAdSelectionSignals;
197     }
198 
199     /**
200      * @return JSON in an AdSelectionSignals object, provided by the SSP and consumed by the JS
201      *     logic fetched from the SSP, represents any information that the SSP used in the ad
202      *     scoring process to tweak the results of the ad selection process (e.g. brand safety
203      *     checks, excluded contextual ads).
204      */
205     @NonNull
getSellerSignals()206     public AdSelectionSignals getSellerSignals() {
207         return mSellerSignals;
208     }
209 
210     /**
211      * @return a Map of buyers and AdSelectionSignals, fetched from the AdSelectionConfig and
212      *     consumed by the JS logic fetched from the DSP, representing any information that each
213      *     buyer would provide during ad selection to participants (such as bid floor, ad selection
214      *     type, etc.)
215      */
216     @NonNull
getPerBuyerSignals()217     public Map<AdTechIdentifier, AdSelectionSignals> getPerBuyerSignals() {
218         return mPerBuyerSignals;
219     }
220 
221     /**
222      * @return a Map of buyers and corresponding Contextual Ads, these ads are expected to be
223      *     pre-downloaded from the contextual path and injected into Ad Selection.
224      * @hide
225      */
226     @NonNull
getBuyerContextualAds()227     public Map<AdTechIdentifier, ContextualAds> getBuyerContextualAds() {
228         return mBuyerContextualAds;
229     }
230 
231     /**
232      * @return URI endpoint of sell-side trusted signal from which creative specific realtime
233      *     information can be fetched from.
234      */
235     @NonNull
getTrustedScoringSignalsUri()236     public Uri getTrustedScoringSignalsUri() {
237         return mTrustedScoringSignalsUri;
238     }
239 
240     /** Builder for {@link AdSelectionConfig} object. */
241     public static final class Builder {
242         private AdTechIdentifier mSeller;
243         private Uri mDecisionLogicUri;
244         private List<AdTechIdentifier> mCustomAudienceBuyers;
245         private AdSelectionSignals mAdSelectionSignals = AdSelectionSignals.EMPTY;
246         private AdSelectionSignals mSellerSignals = AdSelectionSignals.EMPTY;
247         private Map<AdTechIdentifier, AdSelectionSignals> mPerBuyerSignals = Collections.emptyMap();
248         private Map<AdTechIdentifier, ContextualAds> mBuyerContextualAds = Collections.emptyMap();
249         private Uri mTrustedScoringSignalsUri;
250 
Builder()251         public Builder() {}
252 
253         /**
254          * Sets the seller identifier.
255          *
256          * <p>See {@link #getSeller()} for more details.
257          */
258         @NonNull
setSeller(@onNull AdTechIdentifier seller)259         public AdSelectionConfig.Builder setSeller(@NonNull AdTechIdentifier seller) {
260             Objects.requireNonNull(seller);
261 
262             this.mSeller = seller;
263             return this;
264         }
265 
266         /**
267          * Sets the URI used to fetch decision logic for use in the ad selection process.
268          *
269          * <p>See {@link #getDecisionLogicUri()} for more details.
270          */
271         @NonNull
setDecisionLogicUri(@onNull Uri decisionLogicUri)272         public AdSelectionConfig.Builder setDecisionLogicUri(@NonNull Uri decisionLogicUri) {
273             Objects.requireNonNull(decisionLogicUri);
274 
275             this.mDecisionLogicUri = decisionLogicUri;
276             return this;
277         }
278 
279         /**
280          * Sets the list of allowed buyers.
281          *
282          * <p>See {@link #getCustomAudienceBuyers()} for more details.
283          */
284         @NonNull
setCustomAudienceBuyers( @onNull List<AdTechIdentifier> customAudienceBuyers)285         public AdSelectionConfig.Builder setCustomAudienceBuyers(
286                 @NonNull List<AdTechIdentifier> customAudienceBuyers) {
287             Objects.requireNonNull(customAudienceBuyers);
288 
289             this.mCustomAudienceBuyers = customAudienceBuyers;
290             return this;
291         }
292 
293         /**
294          * Sets the signals provided to buyers during ad selection bid generation.
295          *
296          * <p>If not set, defaults to the empty JSON.
297          *
298          * <p>See {@link #getAdSelectionSignals()} for more details.
299          */
300         @NonNull
setAdSelectionSignals( @onNull AdSelectionSignals adSelectionSignals)301         public AdSelectionConfig.Builder setAdSelectionSignals(
302                 @NonNull AdSelectionSignals adSelectionSignals) {
303             Objects.requireNonNull(adSelectionSignals);
304 
305             this.mAdSelectionSignals = adSelectionSignals;
306             return this;
307         }
308 
309         /**
310          * Set the signals used to modify ad selection results.
311          *
312          * <p>If not set, defaults to the empty JSON.
313          *
314          * <p>See {@link #getSellerSignals()} for more details.
315          */
316         @NonNull
setSellerSignals( @onNull AdSelectionSignals sellerSignals)317         public AdSelectionConfig.Builder setSellerSignals(
318                 @NonNull AdSelectionSignals sellerSignals) {
319             Objects.requireNonNull(sellerSignals);
320 
321             this.mSellerSignals = sellerSignals;
322             return this;
323         }
324 
325         /**
326          * Sets the signals provided by each buyer during ad selection.
327          *
328          * <p>If not set, defaults to an empty map.
329          *
330          * <p>See {@link #getPerBuyerSignals()} for more details.
331          */
332         @NonNull
setPerBuyerSignals( @onNull Map<AdTechIdentifier, AdSelectionSignals> perBuyerSignals)333         public AdSelectionConfig.Builder setPerBuyerSignals(
334                 @NonNull Map<AdTechIdentifier, AdSelectionSignals> perBuyerSignals) {
335             Objects.requireNonNull(perBuyerSignals);
336 
337             this.mPerBuyerSignals = perBuyerSignals;
338             return this;
339         }
340 
341         /**
342          * Sets the contextual Ads corresponding to each buyer during ad selection.
343          *
344          * <p>If not set, defaults to an empty map.
345          *
346          * <p>See {@link #getBuyerContextualAds()} ()} for more details.
347          *
348          * @hide
349          */
350         @NonNull
setBuyerContextualAds( @onNull Map<AdTechIdentifier, ContextualAds> buyerContextualAds)351         public AdSelectionConfig.Builder setBuyerContextualAds(
352                 @NonNull Map<AdTechIdentifier, ContextualAds> buyerContextualAds) {
353             Objects.requireNonNull(buyerContextualAds);
354 
355             this.mBuyerContextualAds = buyerContextualAds;
356             return this;
357         }
358 
359         /**
360          * Sets the URI endpoint of sell-side trusted signal from which creative specific realtime
361          * information can be fetched from.
362          *
363          * <p>If {@link Uri#EMPTY} is passed then network call will be skipped and {@link
364          * AdSelectionSignals#EMPTY} will be passed to ad selection.
365          *
366          * <p>See {@link #getTrustedScoringSignalsUri()} for more details.
367          */
368         @NonNull
setTrustedScoringSignalsUri( @onNull Uri trustedScoringSignalsUri)369         public AdSelectionConfig.Builder setTrustedScoringSignalsUri(
370                 @NonNull Uri trustedScoringSignalsUri) {
371             Objects.requireNonNull(trustedScoringSignalsUri);
372 
373             this.mTrustedScoringSignalsUri = trustedScoringSignalsUri;
374             return this;
375         }
376 
377         /**
378          * Builds an {@link AdSelectionConfig} instance.
379          *
380          * @throws NullPointerException if any required params are null
381          */
382         @NonNull
build()383         public AdSelectionConfig build() {
384             Objects.requireNonNull(mSeller);
385             Objects.requireNonNull(mDecisionLogicUri);
386             Objects.requireNonNull(mCustomAudienceBuyers);
387             Objects.requireNonNull(mAdSelectionSignals);
388             Objects.requireNonNull(mSellerSignals);
389             Objects.requireNonNull(mPerBuyerSignals);
390             Objects.requireNonNull(mBuyerContextualAds);
391             Objects.requireNonNull(mTrustedScoringSignalsUri);
392             return new AdSelectionConfig(
393                     mSeller,
394                     mDecisionLogicUri,
395                     mCustomAudienceBuyers,
396                     mAdSelectionSignals,
397                     mSellerSignals,
398                     mPerBuyerSignals,
399                     mBuyerContextualAds,
400                     mTrustedScoringSignalsUri);
401         }
402     }
403 }
404