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.customaudience;
18 
19 import static android.adservices.common.AdDataFixture.getValidFilterAdDataWithAdRenderIdByBuyer;
20 import static android.adservices.customaudience.TrustedBiddingDataFixture.getValidTrustedBiddingDataByBuyer;
21 
22 import android.adservices.common.AdData;
23 import android.adservices.common.AdDataFixture;
24 import android.adservices.common.AdSelectionSignals;
25 import android.adservices.common.AdTechIdentifier;
26 import android.adservices.common.CommonFixture;
27 import android.net.Uri;
28 
29 
30 import java.time.Duration;
31 import java.time.Instant;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.List;
35 import java.util.stream.Collectors;
36 
37 /** Utility class supporting custom audience API unit tests */
38 public final class CustomAudienceFixture {
39 
40     public static final Duration CUSTOM_AUDIENCE_MAX_ACTIVATION_DELAY_IN =
41             Duration.ofMillis(
42                     CommonFixture.FLAGS_FOR_TEST.getFledgeCustomAudienceMaxActivationDelayInMs());
43     public static final Duration CUSTOM_AUDIENCE_MAX_EXPIRE_IN =
44             Duration.ofMillis(CommonFixture.FLAGS_FOR_TEST.getFledgeCustomAudienceMaxExpireInMs());
45     public static final Duration CUSTOM_AUDIENCE_DEFAULT_EXPIRE_IN =
46             Duration.ofMillis(
47                     CommonFixture.FLAGS_FOR_TEST.getFledgeCustomAudienceDefaultExpireInMs());
48     public static final long DAY_IN_SECONDS = 60 * 60 * 24;
49 
50     public static final String VALID_OWNER = CommonFixture.TEST_PACKAGE_NAME;
51     public static final String VALID_NAME = "testCustomAudienceName";
52 
53     public static final Instant VALID_ACTIVATION_TIME =
54             CommonFixture.FIXED_NOW_TRUNCATED_TO_MILLI;
55     public static final Instant VALID_DELAYED_ACTIVATION_TIME =
56             CommonFixture.FIXED_NOW_TRUNCATED_TO_MILLI.plus(
57                     CUSTOM_AUDIENCE_MAX_ACTIVATION_DELAY_IN.dividedBy(2));
58     public static final Instant INVALID_DELAYED_ACTIVATION_TIME =
59             CommonFixture.FIXED_NOW_TRUNCATED_TO_MILLI.plus(
60                     CUSTOM_AUDIENCE_MAX_ACTIVATION_DELAY_IN.multipliedBy(2));
61 
62     public static final Instant VALID_EXPIRATION_TIME =
63             VALID_ACTIVATION_TIME.plus(CUSTOM_AUDIENCE_DEFAULT_EXPIRE_IN);
64     public static final Instant VALID_DELAYED_EXPIRATION_TIME =
65             VALID_DELAYED_ACTIVATION_TIME.plusSeconds(DAY_IN_SECONDS);
66     public static final Instant INVALID_BEFORE_NOW_EXPIRATION_TIME =
67             VALID_ACTIVATION_TIME.minusSeconds(DAY_IN_SECONDS);
68     public static final Instant INVALID_NOW_EXPIRATION_TIME =
69             CommonFixture.FIXED_NOW_TRUNCATED_TO_MILLI.minusSeconds(DAY_IN_SECONDS);
70     public static final Instant INVALID_BEFORE_DELAYED_EXPIRATION_TIME =
71             VALID_DELAYED_ACTIVATION_TIME.minusSeconds(DAY_IN_SECONDS);
72     public static final Instant INVALID_BEYOND_MAX_EXPIRATION_TIME =
73             VALID_ACTIVATION_TIME.plus(CUSTOM_AUDIENCE_MAX_EXPIRE_IN.multipliedBy(2));
74     public static final Instant VALID_LAST_UPDATE_TIME_24_HRS_BEFORE =
75             CommonFixture.FIXED_NOW_TRUNCATED_TO_MILLI.minusSeconds(DAY_IN_SECONDS);
76     public static final Instant INVALID_LAST_UPDATE_TIME_72_DAYS_BEFORE =
77             CommonFixture.FIXED_NOW_TRUNCATED_TO_MILLI.minusSeconds(DAY_IN_SECONDS * 72);
78 
79     public static final AdSelectionSignals VALID_USER_BIDDING_SIGNALS =
80             AdSelectionSignals.fromString("{\"valid\":\"yep\",\"opaque\":\"definitely\"}");
81 
getValidFetchUriByBuyer(AdTechIdentifier buyer, String token)82     public static Uri getValidFetchUriByBuyer(AdTechIdentifier buyer, String token) {
83         boolean hasToken = token != null && !token.isEmpty();
84         return CommonFixture.getUri(buyer, "/ca" + (hasToken ? "?token=" + token : ""));
85     }
86 
getValidFetchUriByBuyer(AdTechIdentifier buyer)87     public static Uri getValidFetchUriByBuyer(AdTechIdentifier buyer) {
88         return getValidFetchUriByBuyer(buyer, null);
89     }
90 
getValidDailyUpdateUriByBuyer(AdTechIdentifier buyer)91     public static Uri getValidDailyUpdateUriByBuyer(AdTechIdentifier buyer) {
92         return CommonFixture.getUri(buyer, "/update");
93     }
94 
getValidBiddingLogicUriByBuyer(AdTechIdentifier buyer)95     public static Uri getValidBiddingLogicUriByBuyer(AdTechIdentifier buyer) {
96         return CommonFixture.getUri(buyer, "/bidding/logic/here/");
97     }
98 
getValidBuilderForBuyer(AdTechIdentifier buyer)99     public static CustomAudience.Builder getValidBuilderForBuyer(AdTechIdentifier buyer) {
100         return new CustomAudience.Builder()
101                 .setBuyer(buyer)
102                 .setName(CustomAudienceFixture.VALID_NAME)
103                 .setActivationTime(CustomAudienceFixture.VALID_ACTIVATION_TIME)
104                 .setExpirationTime(CustomAudienceFixture.VALID_EXPIRATION_TIME)
105                 .setDailyUpdateUri(CustomAudienceFixture.getValidDailyUpdateUriByBuyer(buyer))
106                 .setUserBiddingSignals(CustomAudienceFixture.VALID_USER_BIDDING_SIGNALS)
107                 .setTrustedBiddingData(getValidTrustedBiddingDataByBuyer(buyer))
108                 .setBiddingLogicUri(CustomAudienceFixture.getValidBiddingLogicUriByBuyer(buyer))
109                 .setAds(AdDataFixture.getValidAdsByBuyer(buyer));
110     }
111 
112     /** Build valid CA with server auction flags */
getValidBuilderByBuyerWithAuctionServerRequestFlags( AdTechIdentifier buyer, @CustomAudience.AuctionServerRequestFlag int auctionServerRequestFlags)113     public static CustomAudience.Builder getValidBuilderByBuyerWithAuctionServerRequestFlags(
114             AdTechIdentifier buyer,
115             @CustomAudience.AuctionServerRequestFlag int auctionServerRequestFlags) {
116         return getValidBuilderForBuyer(buyer)
117                 .setAuctionServerRequestFlags(auctionServerRequestFlags);
118     }
119 
getValidBuilderWithSubdomainsForBuyer( AdTechIdentifier buyer)120     public static CustomAudience.Builder getValidBuilderWithSubdomainsForBuyer(
121             AdTechIdentifier buyer) {
122         return getValidBuilderForBuyer(buyer)
123                 .setBiddingLogicUri(
124                         CommonFixture.getUriWithValidSubdomain(buyer.toString(), "/bidding/logic"))
125                 .setDailyUpdateUri(
126                         CommonFixture.getUriWithValidSubdomain(buyer.toString(), "/dailyupdate"))
127                 .setTrustedBiddingData(
128                         new TrustedBiddingData.Builder()
129                                 .setTrustedBiddingUri(
130                                         CommonFixture.getUriWithValidSubdomain(
131                                                 buyer.toString(), "/trustedbidding"))
132                                 .setTrustedBiddingKeys(
133                                         TrustedBiddingDataFixture.VALID_TRUSTED_BIDDING_KEYS)
134                                 .build())
135                 .setAds(
136                         Arrays.asList(
137                                 AdDataFixture.getValidAdDataWithSubdomainBuilderByBuyer(buyer, 0)
138                                         .build(),
139                                 AdDataFixture.getValidAdDataWithSubdomainBuilderByBuyer(buyer, 1)
140                                         .build()));
141     }
142 
143     // TODO(b/266837113) Merge with getValidBuilderForBuyer once filters are unhidden
getValidBuilderForBuyerFilters(AdTechIdentifier buyer)144     public static CustomAudience.Builder getValidBuilderForBuyerFilters(AdTechIdentifier buyer) {
145         return new CustomAudience.Builder()
146                 .setBuyer(buyer)
147                 .setName(CustomAudienceFixture.VALID_NAME)
148                 .setActivationTime(CustomAudienceFixture.VALID_ACTIVATION_TIME)
149                 .setExpirationTime(CustomAudienceFixture.VALID_EXPIRATION_TIME)
150                 .setDailyUpdateUri(CustomAudienceFixture.getValidDailyUpdateUriByBuyer(buyer))
151                 .setUserBiddingSignals(CustomAudienceFixture.VALID_USER_BIDDING_SIGNALS)
152                 .setTrustedBiddingData(getValidTrustedBiddingDataByBuyer(buyer))
153                 .setBiddingLogicUri(CustomAudienceFixture.getValidBiddingLogicUriByBuyer(buyer))
154                 .setAds(AdDataFixture.getValidFilterAdsByBuyer(buyer));
155     }
156 
157     /** Build valid CA with filters and render id */
getValidBuilderForBuyerFiltersWithAdRenderId( AdTechIdentifier buyer)158     public static CustomAudience.Builder getValidBuilderForBuyerFiltersWithAdRenderId(
159             AdTechIdentifier buyer) {
160         return new CustomAudience.Builder()
161                 .setBuyer(buyer)
162                 .setName(CustomAudienceFixture.VALID_NAME)
163                 .setActivationTime(CustomAudienceFixture.VALID_ACTIVATION_TIME)
164                 .setExpirationTime(CustomAudienceFixture.VALID_EXPIRATION_TIME)
165                 .setDailyUpdateUri(CustomAudienceFixture.getValidDailyUpdateUriByBuyer(buyer))
166                 .setUserBiddingSignals(CustomAudienceFixture.VALID_USER_BIDDING_SIGNALS)
167                 .setTrustedBiddingData(getValidTrustedBiddingDataByBuyer(buyer))
168                 .setBiddingLogicUri(CustomAudienceFixture.getValidBiddingLogicUriByBuyer(buyer))
169                 .setAds(AdDataFixture.getValidFilterAdsWithAdRenderIdByBuyer(buyer));
170     }
171 
172     /** Build N valid CAs with filters and render id */
getNValidCustomAudiences( int nBuyers, int nCAsPerBuyer, int nAdsPerCA)173     public static List<CustomAudience> getNValidCustomAudiences(
174             int nBuyers, int nCAsPerBuyer, int nAdsPerCA) {
175         List<CustomAudience> customAudiences = new ArrayList<>();
176         for (int b = 0; b < nBuyers; b++) {
177             AdTechIdentifier buyer = AdTechIdentifier.fromString("buyer%d.com".formatted(b));
178             for (int c = 0; c < nCAsPerBuyer; c++) {
179                 List<AdData> ads = new ArrayList<>();
180                 for (int a = 0; a < nAdsPerCA; a++) {
181                     ads.add(
182                             getValidFilterAdDataWithAdRenderIdByBuyer(
183                                     buyer, /* sequenceString= */ generateHash(a, b, c)));
184                 }
185                 CustomAudience customAudience =
186                         new CustomAudience.Builder()
187                                 .setBuyer(buyer)
188                                 .setName("testCustomAudience_%s".formatted(generateHash(b, c)))
189                                 .setActivationTime(VALID_ACTIVATION_TIME)
190                                 .setExpirationTime(VALID_EXPIRATION_TIME)
191                                 .setDailyUpdateUri(getValidDailyUpdateUriByBuyer(buyer))
192                                 .setBiddingLogicUri(getValidBiddingLogicUriByBuyer(buyer))
193                                 .setUserBiddingSignals(VALID_USER_BIDDING_SIGNALS)
194                                 .setTrustedBiddingData(getValidTrustedBiddingDataByBuyer(buyer))
195                                 .setAds(ads)
196                                 .build();
197                 customAudiences.add(customAudience);
198             }
199         }
200         return customAudiences;
201     }
202 
generateHash(int... vargs)203     private static String generateHash(int... vargs) {
204         return Arrays.stream(vargs).mapToObj(String::valueOf).collect(Collectors.joining("-"));
205     }
206 }
207