1 /*
2  * Copyright (C) 2024 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.adselection;
18 
19 import static com.android.adservices.flags.Flags.FLAG_FLEDGE_GET_AD_SELECTION_DATA_SELLER_CONFIGURATION_ENABLED;
20 
21 import android.adservices.common.AdTechIdentifier;
22 import android.annotation.FlaggedApi;
23 import android.annotation.IntRange;
24 import android.annotation.NonNull;
25 import android.os.OutcomeReceiver;
26 import android.os.Parcel;
27 import android.os.Parcelable;
28 
29 import java.util.Objects;
30 import java.util.concurrent.Executor;
31 
32 /**
33  * Contains a per buyer configuration which will be used as part of a {@link SellerConfiguration} in
34  * a {@link GetAdSelectionDataRequest}.
35  *
36  * <p>This object will be created by the calling SDK as part of creating the seller configuration.
37  */
38 @FlaggedApi(FLAG_FLEDGE_GET_AD_SELECTION_DATA_SELLER_CONFIGURATION_ENABLED)
39 public final class PerBuyerConfiguration implements Parcelable {
40     @NonNull private final AdTechIdentifier mBuyer;
41     private final int mTargetInputSizeBytes;
42 
PerBuyerConfiguration(Parcel in)43     private PerBuyerConfiguration(Parcel in) {
44         mBuyer = AdTechIdentifier.CREATOR.createFromParcel(in);
45         mTargetInputSizeBytes = in.readInt();
46     }
47 
PerBuyerConfiguration(@onNull AdTechIdentifier buyer, int targetInputSizeBytes)48     private PerBuyerConfiguration(@NonNull AdTechIdentifier buyer, int targetInputSizeBytes) {
49         Objects.requireNonNull(buyer, "Buyer must be set.");
50 
51         mBuyer = buyer;
52         mTargetInputSizeBytes = targetInputSizeBytes;
53     }
54 
55     @NonNull
56     public static final Creator<PerBuyerConfiguration> CREATOR =
57             new Creator<PerBuyerConfiguration>() {
58                 @Override
59                 public PerBuyerConfiguration createFromParcel(@NonNull Parcel in) {
60                     Objects.requireNonNull(in);
61                     return new PerBuyerConfiguration(in);
62                 }
63 
64                 @Override
65                 public PerBuyerConfiguration[] newArray(int size) {
66                     return new PerBuyerConfiguration[size];
67                 }
68             };
69 
70     @Override
describeContents()71     public int describeContents() {
72         return 0;
73     }
74 
75     @Override
writeToParcel(@onNull Parcel dest, int flags)76     public void writeToParcel(@NonNull Parcel dest, int flags) {
77         mBuyer.writeToParcel(dest, flags);
78         dest.writeInt(mTargetInputSizeBytes);
79     }
80 
81     /** Returns the buyer associated with this per buyer configuration. */
82     @NonNull
getBuyer()83     public AdTechIdentifier getBuyer() {
84         return mBuyer;
85     }
86 
87     /**
88      * The service will make a best effort attempt to include this amount of bytes into the response
89      * of {@link AdSelectionManager#getAdSelectionData(GetAdSelectionDataRequest, Executor,
90      * OutcomeReceiver)} for this buyer.
91      *
92      * <p>If this is zero this buyer will share remaining space after other buyers' target sizes are
93      * respected.
94      */
95     @IntRange(from = 0, to = Integer.MAX_VALUE)
getTargetInputSizeBytes()96     public int getTargetInputSizeBytes() {
97         return mTargetInputSizeBytes;
98     }
99 
100     @Override
equals(Object o)101     public boolean equals(Object o) {
102         if (o instanceof PerBuyerConfiguration) {
103             PerBuyerConfiguration perBuyerConfiguration = (PerBuyerConfiguration) o;
104             return Objects.equals(mBuyer, perBuyerConfiguration.mBuyer)
105                     && mTargetInputSizeBytes == perBuyerConfiguration.mTargetInputSizeBytes;
106         }
107         return false;
108     }
109 
110     @Override
hashCode()111     public int hashCode() {
112         return Objects.hash(mBuyer, mTargetInputSizeBytes);
113     }
114 
115     /** Builder for {@link PerBuyerConfiguration} objects. */
116     public static final class Builder {
117         @NonNull private AdTechIdentifier mBuyer = null;
118         private int mTargetInputSizeBytes;
119 
120         /** Creates a new {@link Builder}. */
Builder()121         public Builder() {}
122 
123         /** Sets the buyer for this configuration. See {@link #getBuyer()} for more details. */
124         @NonNull
setBuyer(@onNull AdTechIdentifier buyer)125         public Builder setBuyer(@NonNull AdTechIdentifier buyer) {
126             Objects.requireNonNull(buyer);
127             mBuyer = buyer;
128             return this;
129         }
130 
131         /**
132          * Sets the target input size in bytes for this configuration.
133          *
134          * <p>If this is not explicitly set, this buyer will share remaining space after other
135          * buyers' target sizes are respected. See {@link #getTargetInputSizeBytes()} for more
136          * details.
137          */
138         @NonNull
setTargetInputSizeBytes( @ntRangefrom = 0, to = Integer.MAX_VALUE) int targetInputSizeB)139         public Builder setTargetInputSizeBytes(
140                 @IntRange(from = 0, to = Integer.MAX_VALUE) int targetInputSizeB) {
141             mTargetInputSizeBytes = targetInputSizeB;
142             return this;
143         }
144 
145         /** Builds a {@link PerBuyerConfiguration} instance. */
146         @NonNull
build()147         public PerBuyerConfiguration build() {
148             Objects.requireNonNull(mBuyer);
149             if (mTargetInputSizeBytes < 0) {
150                 throw new IllegalArgumentException("Target input size must be non-negative.");
151             }
152 
153             return new PerBuyerConfiguration(mBuyer, mTargetInputSizeBytes);
154         }
155     }
156 }
157