• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 com.android.adservices.service.adselection.signature;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import android.adservices.adselection.AdWithBid;
22 import android.adservices.adselection.SignedContextualAds;
23 import android.adservices.common.AdData;
24 import android.adservices.common.AdFilters;
25 import android.adservices.common.AdTechIdentifier;
26 import android.adservices.common.AppInstallFilters;
27 import android.adservices.common.FrequencyCapFilters;
28 import android.adservices.common.KeyedFrequencyCap;
29 import android.net.Uri;
30 
31 import com.android.adservices.shared.testing.SdkLevelSupportRule;
32 
33 import com.google.common.collect.ImmutableList;
34 
35 import org.junit.Before;
36 import org.junit.Rule;
37 import org.junit.Test;
38 
39 import java.nio.charset.StandardCharsets;
40 import java.time.Duration;
41 import java.util.Arrays;
42 import java.util.Collections;
43 import java.util.Set;
44 import java.util.stream.Collectors;
45 
46 public class BinarySerializerSignedContextualAdsTest {
47     public static final byte[] TEST_SIGNATURE = new byte[] {0, 1, 2};
48 
49     private SignedContextualAdsHashUtil mSerializer;
50 
51     @Rule(order = 0)
52     public final SdkLevelSupportRule sdkLevel = SdkLevelSupportRule.forAtLeastS();
53 
54     @Before
setUp()55     public void setUp() {
56         mSerializer = new SignedContextualAdsHashUtil();
57     }
58 
59     @Test
testWriteString()60     public void testWriteString() {
61         String testString = "Hello";
62         mSerializer.writeString(testString);
63         assertThat(bytesToString(mSerializer.getBytes())).isEqualTo(testString);
64     }
65 
66     @Test
testWriteLong()67     public void testWriteLong() {
68         long testLong = 123456789L;
69         mSerializer.writeLong(testLong);
70         assertThat(bytesToString(mSerializer.getBytes())).isEqualTo("" + testLong);
71     }
72 
73     @Test
testWriteDouble()74     public void testWriteDouble() {
75         double testDouble = 123.45;
76         mSerializer.writeDouble(testDouble);
77         assertThat(bytesToString(mSerializer.getBytes())).isEqualTo("" + testDouble);
78     }
79 
80     @Test
testWriteInt()81     public void testWriteInt() {
82         int testInt = 123;
83         mSerializer.writeInt(testInt);
84         assertThat(bytesToString(mSerializer.getBytes())).isEqualTo("" + testInt);
85     }
86 
87     @Test
testContextualAdSerialization_fullObject_success()88     public void testContextualAdSerialization_fullObject_success() {
89         String buyer = "https://example.com";
90         String decisionLogicUri = "example.com/decisionLogic";
91         String metadata = "metadata";
92         String adCounterKeys = "1,2,3";
93         String adRenderUri = "example.com/render";
94         String bid = "5.10";
95         int adCounterKey = 42;
96         int maxCount = 43;
97         Duration oneDay = Duration.ofDays(1);
98         KeyedFrequencyCap keyedFrequencyCap =
99                 new KeyedFrequencyCap.Builder(adCounterKey, maxCount, oneDay).build();
100         FrequencyCapFilters frequencyCapFilters =
101                 new FrequencyCapFilters.Builder()
102                         .setKeyedFrequencyCapsForClickEvents(
103                                 Collections.singletonList(keyedFrequencyCap))
104                         .setKeyedFrequencyCapsForWinEvents(
105                                 Collections.singletonList(keyedFrequencyCap))
106                         .setKeyedFrequencyCapsForImpressionEvents(
107                                 Collections.singletonList(keyedFrequencyCap))
108                         .setKeyedFrequencyCapsForViewEvents(
109                                 Collections.singletonList(keyedFrequencyCap))
110                         .build();
111         Set<String> packageNames = Set.of("com.awesome.app1", "com.awesome.app2");
112         AdFilters adFilters =
113                 new AdFilters.Builder()
114                         .setFrequencyCapFilters(frequencyCapFilters)
115                         .setAppInstallFilters(
116                                 new AppInstallFilters.Builder()
117                                         .setPackageNames(packageNames)
118                                         .build())
119                         .build();
120         String adRenderId = "987";
121 
122         Set<Integer> adCounterKeysSet =
123                 Arrays.stream(adCounterKeys.split(","))
124                         .map(Integer::valueOf)
125                         .collect(Collectors.toSet());
126         SignedContextualAds contextualAds =
127                 new SignedContextualAds.Builder()
128                         .setBuyer(AdTechIdentifier.fromString(buyer))
129                         .setDecisionLogicUri(Uri.parse(decisionLogicUri))
130                         .setAdsWithBid(
131                                 ImmutableList.of(
132                                         new AdWithBid(
133                                                 new AdData.Builder()
134                                                         .setMetadata(metadata)
135                                                         .setAdFilters(adFilters)
136                                                         .setAdRenderId(adRenderId)
137                                                         .setAdCounterKeys(adCounterKeysSet)
138                                                         .setRenderUri(Uri.parse(adRenderUri))
139                                                         .build(),
140                                                 Double.parseDouble(bid))))
141                         .setSignature(TEST_SIGNATURE)
142                         .build();
143 
144         byte[] serialized = new SignedContextualAdsHashUtil().serialize(contextualAds);
145 
146         /*
147          * This serialization is created manually following the rules explained in
148          * SignedContextualAds. Our serialization has to exactly match this to have consistency
149          * between ad tech and PPAPI.
150          */
151         String expected =
152                 String.format(
153                         "buyer=%s|decision_logic_uri=%s|ads_with_bid=ad_data=ad_counter_keys=%s|"
154                                 + "ad_filters=app_install_filters=package_names=%s||"
155                                 + "frequency_cap_filters=keyed_frequency_caps_for_click_events="
156                                 + "ad_counter_key=%s|interval=%s|max_count=%s||"
157                                 + "keyed_frequency_caps_for_impression_events=ad_counter_key=%s|"
158                                 + "interval=%s|max_count=%s||keyed_frequency_caps_for_view_events="
159                                 + "ad_counter_key=%s|interval=%s|max_count=%s||"
160                                 + "keyed_frequency_caps_for_win_events=ad_counter_key=%s|"
161                                 + "interval=%s|max_count=%s||||ad_render_id=%s|metadata=%s|"
162                                 + "render_uri=%s||bid=%s||",
163                         buyer,
164                         decisionLogicUri,
165                         adCounterKeys,
166                         packageNames.stream().sorted().collect(Collectors.joining(",")),
167                         adCounterKey,
168                         oneDay.toMillis(),
169                         maxCount,
170                         adCounterKey,
171                         oneDay.toMillis(),
172                         maxCount,
173                         adCounterKey,
174                         oneDay.toMillis(),
175                         maxCount,
176                         adCounterKey,
177                         oneDay.toMillis(),
178                         maxCount,
179                         adRenderId,
180                         metadata,
181                         adRenderUri,
182                         bid);
183         assertThat(bytesToString(serialized)).isEqualTo(expected);
184     }
185 
186     @Test
testContextualAdSerialization_minimalistObject_success()187     public void testContextualAdSerialization_minimalistObject_success() {
188         String buyer = "https://example.com";
189         String decisionLogicUri = "example.com/decisionLogic";
190         String metadata = "metadata";
191         String adCounterKeys = "1,2,3";
192         String adRenderUri = "example.com/render";
193         String bid = "5.10";
194         SignedContextualAds contextualAds =
195                 new SignedContextualAds.Builder()
196                         .setBuyer(AdTechIdentifier.fromString(buyer))
197                         .setDecisionLogicUri(Uri.parse(decisionLogicUri))
198                         .setAdsWithBid(
199                                 ImmutableList.of(
200                                         new AdWithBid(
201                                                 new AdData.Builder()
202                                                         .setMetadata(metadata)
203                                                         .setAdCounterKeys(
204                                                                 Arrays.stream(
205                                                                                 adCounterKeys.split(
206                                                                                         ","))
207                                                                         .map(Integer::valueOf)
208                                                                         .collect(
209                                                                                 Collectors.toSet()))
210                                                         .setRenderUri(Uri.parse(adRenderUri))
211                                                         .build(),
212                                                 Double.parseDouble(bid))))
213                         .setSignature(TEST_SIGNATURE)
214                         .build();
215 
216         byte[] serialized = new SignedContextualAdsHashUtil().serialize(contextualAds);
217 
218         String expected =
219                 String.format(
220                         "buyer=%s|decision_logic_uri=%s|ads_with_bid=ad_data=ad_counter_keys=%s|"
221                                 + "metadata=%s|render_uri=%s||bid=%s||",
222                         buyer, decisionLogicUri, adCounterKeys, metadata, adRenderUri, bid);
223         assertThat(bytesToString(serialized)).isEqualTo(expected);
224     }
225 
bytesToString(byte[] bytes)226     private String bytesToString(byte[] bytes) {
227         return new String(bytes, StandardCharsets.UTF_8);
228     }
229 }
230