• 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 
17 package com.android.adservices.service.measurement;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertNotEquals;
23 import static org.junit.Assert.assertNotNull;
24 import static org.junit.Assert.assertNull;
25 import static org.junit.Assert.assertThrows;
26 import static org.junit.Assert.assertTrue;
27 import static org.mockito.Mockito.when;
28 
29 import android.net.Uri;
30 
31 import com.android.adservices.common.WebUtil;
32 import com.android.adservices.service.Flags;
33 import com.android.adservices.service.measurement.TriggerFixture.ValidTriggerParams;
34 import com.android.adservices.service.measurement.aggregation.AggregatableAttributionTrigger;
35 import com.android.adservices.service.measurement.aggregation.AggregatableKeyValue;
36 import com.android.adservices.service.measurement.aggregation.AggregatableValuesConfig;
37 import com.android.adservices.service.measurement.aggregation.AggregateDebugReportData;
38 import com.android.adservices.service.measurement.aggregation.AggregateDebugReporting;
39 import com.android.adservices.service.measurement.aggregation.AggregateTriggerData;
40 import com.android.adservices.service.measurement.reporting.DebugReportApi;
41 import com.android.adservices.service.measurement.util.UnsignedLong;
42 
43 import org.json.JSONArray;
44 import org.json.JSONException;
45 import org.json.JSONObject;
46 import org.junit.Test;
47 import org.junit.runner.RunWith;
48 import org.mockito.Mock;
49 import org.mockito.junit.MockitoJUnitRunner;
50 
51 import java.math.BigInteger;
52 import java.util.ArrayList;
53 import java.util.Arrays;
54 import java.util.Collections;
55 import java.util.HashSet;
56 import java.util.List;
57 import java.util.Map;
58 import java.util.Optional;
59 import java.util.Set;
60 
61 @RunWith(MockitoJUnitRunner.class)
62 public class TriggerTest {
63     private static final String TOP_LEVEL_FILTERS_JSON_STRING =
64             "[{\n"
65                     + "  \"key_1\": [\"value_1\", \"value_2\"],\n"
66                     + "  \"key_2\": [\"value_1\", \"value_2\"]\n"
67                     + "}]\n";
68 
69     private static final String TOP_LEVEL_FILTERS_JSON_STRING_X =
70             "[{\n"
71                     + "  \"key_1x\": [\"value_1\", \"value_2\"],\n"
72                     + "  \"key_2x\": [\"value_1\", \"value_2\"]\n"
73                     + "}]\n";
74 
75     private static final String EVENT_TRIGGERS =
76             "[\n"
77                     + "{\n"
78                     + "  \"trigger_data\": \"1\",\n"
79                     + "  \"priority\": \"345678\",\n"
80                     + "  \"deduplication_key\": \"2345678\",\n"
81                     + "  \"filters\": [{\n"
82                     + "    \"source_type\": [\"navigation\"],\n"
83                     + "    \"key_1\": [\"value_1\"] \n"
84                     + "   }]\n"
85                     + "}"
86                     + "]\n";
87 
88     private static final UnsignedLong DEBUG_KEY = new UnsignedLong(2367372L);
89     private static final Uri APP_DESTINATION = Uri.parse("android-app://com.android.app");
90     private static final Uri APP_DESTINATION_WITH_PATH =
91             Uri.parse("android-app://com.android.app/with/path");
92     private static final Uri WEB_DESTINATION = WebUtil.validUri("https://example.test");
93     private static final Uri WEB_DESTINATION_WITH_PATH =
94             WebUtil.validUri("https://example.test/with/path");
95     private static final Uri WEB_DESTINATION_WITH_SUBDOMAIN =
96             WebUtil.validUri("https://subdomain.example.test");
97     private static final Uri WEB_DESTINATION_WITH_SUBDOMAIN_PATH_QUERY_FRAGMENT =
98             WebUtil.validUri("https://subdomain.example.test/with/path?query=0#fragment");
99     private static final Uri WEB_DESTINATION_INVALID = Uri.parse("https://example.notatld");
100 
101     @Mock Flags mFlags;
102 
103     @Test
testEqualsPass()104     public void testEqualsPass() throws JSONException {
105         assertEquals(TriggerFixture.getValidTriggerBuilder().build(),
106                 TriggerFixture.getValidTriggerBuilder().build());
107         JSONArray aggregateTriggerDatas = new JSONArray();
108         JSONObject aggregateTriggerData1  = new JSONObject();
109         aggregateTriggerData1.put("key_piece", "0x400");
110         aggregateTriggerData1.put("source_keys", Arrays.asList("campaignCounts"));
111         JSONObject aggregateTriggerData2  = new JSONObject();
112         aggregateTriggerData2.put("key_piece", "0xA80");
113         aggregateTriggerData2.put("source_keys", Arrays.asList("geoValue", "nonMatchingKey"));
114         aggregateTriggerDatas.put(aggregateTriggerData1);
115         aggregateTriggerDatas.put(aggregateTriggerData2);
116         JSONObject values  = new JSONObject();
117         values.put("campaignCounts", 32768);
118         values.put("geoValue", 1664);
119         JSONObject adtechBitMapping = new JSONObject();
120         adtechBitMapping.put("AdTechA-enrollment_id", "0x1");
121         String debugJoinKey = "SAMPLE_DEBUG_JOIN_KEY";
122         String debugAppAdId = "SAMPLE_DEBUG_APP_ADID";
123         String debugWebAdId = "SAMPLE_DEBUG_WEB_ADID";
124         assertEquals(
125                 TriggerFixture.getValidTriggerBuilder()
126                         .setEnrollmentId("enrollment-id")
127                         .setAttributionDestination(Uri.parse("https://example.test/aD"))
128                         .setDestinationType(EventSurfaceType.WEB)
129                         .setId("1")
130                         .setEventTriggers(EVENT_TRIGGERS)
131                         .setTriggerTime(5L)
132                         .setIsDebugReporting(true)
133                         .setAdIdPermission(true)
134                         .setArDebugPermission(true)
135                         .setStatus(Trigger.Status.PENDING)
136                         .setRegistrant(Uri.parse("android-app://com.example.abc"))
137                         .setAggregateTriggerData(aggregateTriggerDatas.toString())
138                         .setAggregateValuesString(values.toString())
139                         .setFilters(TOP_LEVEL_FILTERS_JSON_STRING)
140                         .setNotFilters(TOP_LEVEL_FILTERS_JSON_STRING)
141                         .setDebugKey(DEBUG_KEY)
142                         .setAggregatableAttributionTrigger(
143                                 TriggerFixture.getValidTrigger()
144                                         .getAggregatableAttributionTrigger(mFlags)
145                                         .orElse(null))
146                         .setAttributionConfig(createAttributionConfigJSONArray().toString())
147                         .setAdtechBitMapping(adtechBitMapping.toString())
148                         .setDebugJoinKey(debugJoinKey)
149                         .setPlatformAdId(debugAppAdId)
150                         .setDebugAdId(debugWebAdId)
151                         .setRegistrationOrigin(
152                                 TriggerFixture.ValidTriggerParams.REGISTRATION_ORIGIN)
153                         .setAttributionScopesString(
154                                 TriggerFixture.ValidTriggerParams.ATTRIBUTION_SCOPES)
155                         .setAggregatableFilteringIdMaxBytes(
156                                 TriggerFixture.ValidTriggerParams
157                                         .AGGREGATABLE_FILTERING_ID_MAX_BYTES)
158                         .setAggregateDebugReportingString(
159                                 TriggerFixture.ValidTriggerParams.AGGREGATE_DEBUG_REPORT)
160                         .build(),
161                 TriggerFixture.getValidTriggerBuilder()
162                         .setEnrollmentId("enrollment-id")
163                         .setAttributionDestination(Uri.parse("https://example.test/aD"))
164                         .setDestinationType(EventSurfaceType.WEB)
165                         .setId("1")
166                         .setEventTriggers(EVENT_TRIGGERS)
167                         .setTriggerTime(5L)
168                         .setIsDebugReporting(true)
169                         .setAdIdPermission(true)
170                         .setArDebugPermission(true)
171                         .setStatus(Trigger.Status.PENDING)
172                         .setRegistrant(Uri.parse("android-app://com.example.abc"))
173                         .setAggregateTriggerData(aggregateTriggerDatas.toString())
174                         .setAggregateValuesString(values.toString())
175                         .setFilters(TOP_LEVEL_FILTERS_JSON_STRING)
176                         .setNotFilters(TOP_LEVEL_FILTERS_JSON_STRING)
177                         .setDebugKey(DEBUG_KEY)
178                         .setAggregatableAttributionTrigger(
179                                 TriggerFixture.getValidTrigger()
180                                         .getAggregatableAttributionTrigger(mFlags)
181                                         .orElse(null))
182                         .setAttributionConfig(createAttributionConfigJSONArray().toString())
183                         .setAdtechBitMapping(adtechBitMapping.toString())
184                         .setDebugJoinKey(debugJoinKey)
185                         .setPlatformAdId(debugAppAdId)
186                         .setDebugAdId(debugWebAdId)
187                         .setRegistrationOrigin(
188                                 TriggerFixture.ValidTriggerParams.REGISTRATION_ORIGIN)
189                         .setAttributionScopesString(
190                                 TriggerFixture.ValidTriggerParams.ATTRIBUTION_SCOPES)
191                         .setAggregatableFilteringIdMaxBytes(
192                                 TriggerFixture.ValidTriggerParams
193                                         .AGGREGATABLE_FILTERING_ID_MAX_BYTES)
194                         .setAggregateDebugReportingString(
195                                 TriggerFixture.ValidTriggerParams.AGGREGATE_DEBUG_REPORT)
196                         .build());
197     }
198 
199     @Test
testEqualsFail()200     public void testEqualsFail() throws JSONException {
201         assertNotEquals(
202                 TriggerFixture.getValidTriggerBuilder().setId("1").build(),
203                 TriggerFixture.getValidTriggerBuilder().setId("2").build());
204         assertNotEquals(
205                 TriggerFixture.getValidTriggerBuilder()
206                         .setAttributionDestination(Uri.parse("https://1.test")).build(),
207                 TriggerFixture.getValidTriggerBuilder()
208                         .setAttributionDestination(Uri.parse("https://2.test")).build());
209         assertNotEquals(
210                 TriggerFixture.getValidTriggerBuilder()
211                         .setDestinationType(EventSurfaceType.APP).build(),
212                 TriggerFixture.getValidTriggerBuilder()
213                         .setDestinationType(EventSurfaceType.WEB).build());
214         assertNotEquals(
215                 TriggerFixture.getValidTriggerBuilder()
216                         .setEnrollmentId("enrollment-id-1").build(),
217                 TriggerFixture.getValidTriggerBuilder()
218                         .setEnrollmentId("enrollment-id-2").build());
219         assertNotEquals(
220                 TriggerFixture.getValidTriggerBuilder().setEventTriggers("a").build(),
221                 TriggerFixture.getValidTriggerBuilder().setEventTriggers("b").build());
222         assertNotEquals(
223                 TriggerFixture.getValidTriggerBuilder().setTriggerTime(1L).build(),
224                 TriggerFixture.getValidTriggerBuilder().setTriggerTime(2L).build());
225         assertNotEquals(
226                 TriggerFixture.getValidTriggerBuilder()
227                         .setStatus(Trigger.Status.PENDING).build(),
228                 TriggerFixture.getValidTriggerBuilder()
229                         .setStatus(Trigger.Status.IGNORED).build());
230         assertNotEquals(
231                 TriggerFixture.getValidTriggerBuilder()
232                         .setRegistrant(Uri.parse("android-app://com.example.abc"))
233                         .build(),
234                 TriggerFixture.getValidTriggerBuilder()
235                         .setRegistrant(Uri.parse("android-app://com.example.xyz"))
236                         .build());
237         JSONArray aggregateTriggerDataList1 = new JSONArray();
238         JSONObject aggregateTriggerData1  = new JSONObject();
239         aggregateTriggerData1.put("key_piece", "0x400");
240         aggregateTriggerData1.put("source_keys", Arrays.asList("campaignCounts"));
241         aggregateTriggerDataList1.put(aggregateTriggerData1);
242         JSONArray aggregateTriggerDataList2 = new JSONArray();
243         JSONObject aggregateTriggerData2  = new JSONObject();
244         aggregateTriggerData2.put("key_piece", "0xA80");
245         aggregateTriggerData2.put("source_keys", Arrays.asList("geoValue", "nonMatchingKey"));
246         aggregateTriggerDataList2.put(aggregateTriggerData2);
247         assertNotEquals(
248                 TriggerFixture.getValidTriggerBuilder()
249                         .setAggregateTriggerData(aggregateTriggerDataList1.toString()).build(),
250                 TriggerFixture.getValidTriggerBuilder()
251                         .setAggregateTriggerData(aggregateTriggerDataList2.toString()).build());
252         JSONObject values1  = new JSONObject();
253         values1.put("campaignCounts", 32768);
254         JSONObject values2  = new JSONObject();
255         values2.put("geoValue", 1664);
256         assertThat(
257                         TriggerFixture.getValidTriggerBuilder()
258                                 .setAggregateValuesString(values1.toString())
259                                 .build())
260                 .isNotEqualTo(
261                         TriggerFixture.getValidTriggerBuilder()
262                                 .setAggregateValuesString(values2.toString())
263                                 .build());
264         assertNotEquals(
265                 TriggerFixture.getValidTriggerBuilder()
266                         .setFilters(TOP_LEVEL_FILTERS_JSON_STRING).build(),
267                 TriggerFixture.getValidTriggerBuilder()
268                         .setFilters(TOP_LEVEL_FILTERS_JSON_STRING_X).build());
269         assertNotEquals(
270                 TriggerFixture.getValidTriggerBuilder()
271                         .setNotFilters(TOP_LEVEL_FILTERS_JSON_STRING).build(),
272                 TriggerFixture.getValidTriggerBuilder()
273                         .setNotFilters(TOP_LEVEL_FILTERS_JSON_STRING_X).build());
274         JSONArray attributionConfigList1 = new JSONArray();
275         JSONObject attributionConfig1 = new JSONObject();
276         attributionConfig1.put("source_network", "AdTech1-Ads");
277         JSONObject sourcePriorityRange1 = new JSONObject();
278         sourcePriorityRange1.put("start", 100);
279         sourcePriorityRange1.put("end", 1000);
280         attributionConfig1.put("source_priority_range", sourcePriorityRange1);
281         JSONObject sourceFilters1 = new JSONObject();
282         sourceFilters1.put("campaign_type", Arrays.asList("install"));
283         sourceFilters1.put("source_type", Arrays.asList("navigation"));
284         attributionConfig1.put("source_filters", sourceFilters1);
285         attributionConfig1.put("priority", "99");
286         attributionConfig1.put("expiry", "604800");
287         JSONObject filterData1 = new JSONObject();
288         filterData1.put("campaign_type", Arrays.asList("install"));
289         attributionConfig1.put("filter_data", filterData1);
290         attributionConfigList1.put(attributionConfig1);
291 
292         JSONArray attributionConfigList2 = new JSONArray();
293         JSONObject attributionConfig2 = new JSONObject();
294         attributionConfig2.put("source_network", "AdTech2-Ads");
295         JSONObject sourcePriorityRange2 = new JSONObject();
296         sourcePriorityRange2.put("start", 100);
297         sourcePriorityRange2.put("end", 1000);
298         attributionConfig1.put("source_priority_range", sourcePriorityRange2);
299         JSONObject sourceFilters2 = new JSONObject();
300         sourceFilters2.put("campaign_type", Arrays.asList("install"));
301         sourceFilters2.put("source_type", Arrays.asList("navigation"));
302         attributionConfig2.put("source_filters", sourceFilters2);
303         attributionConfig2.put("priority", "99");
304         attributionConfig2.put("expiry", "604800");
305         JSONObject filterData2 = new JSONObject();
306         filterData1.put("campaign_type", Arrays.asList("install"));
307         attributionConfig2.put("filter_data", filterData2);
308         attributionConfigList2.put(attributionConfig2);
309         assertNotEquals(
310                 TriggerFixture.getValidTriggerBuilder()
311                         .setAttributionConfig(attributionConfigList1.toString())
312                         .build(),
313                 TriggerFixture.getValidTriggerBuilder()
314                         .setAttributionConfig(attributionConfigList2.toString())
315                         .build());
316         JSONObject adtechBitMapping1 = new JSONObject();
317         adtechBitMapping1.put("AdTechA-enrollment_id", "0x1");
318         JSONObject adtechBitMapping2 = new JSONObject();
319         adtechBitMapping2.put("AdTechA-enrollment_id", "0x2");
320         assertNotEquals(
321                 TriggerFixture.getValidTriggerBuilder()
322                         .setAdtechBitMapping(adtechBitMapping1.toString())
323                         .build(),
324                 TriggerFixture.getValidTriggerBuilder()
325                         .setAdtechBitMapping(adtechBitMapping2.toString())
326                         .build());
327         assertNotEquals(
328                 TriggerFixture.getValidTriggerBuilder().setDebugJoinKey("debug_key-1").build(),
329                 TriggerFixture.getValidTriggerBuilder().setDebugJoinKey("debug_key-2").build());
330         assertNotEquals(
331                 TriggerFixture.getValidTriggerBuilder().setPlatformAdId("debugAppAdId1").build(),
332                 TriggerFixture.getValidTriggerBuilder().setPlatformAdId("debugAppAdId2").build());
333         assertNotEquals(
334                 TriggerFixture.getValidTriggerBuilder().setDebugAdId("debugWebAdId1").build(),
335                 TriggerFixture.getValidTriggerBuilder().setDebugAdId("debugWebAdId2").build());
336         assertNotEquals(
337                 TriggerFixture.getValidTriggerBuilder()
338                         .setRegistrationOrigin(WebUtil.validUri("https://subdomain1.example.test"))
339                         .build(),
340                 TriggerFixture.getValidTriggerBuilder()
341                         .setRegistrationOrigin(WebUtil.validUri("https://subdomain2.example.test"))
342                         .build());
343         assertNotEquals(
344                 TriggerFixture.getValidTriggerBuilder().setAttributionScopesString("1").build(),
345                 TriggerFixture.getValidTriggerBuilder().setAttributionScopesString("2").build());
346         assertNotEquals(
347                 TriggerFixture.getValidTriggerBuilder()
348                         .setAggregatableFilteringIdMaxBytes(1)
349                         .build(),
350                 TriggerFixture.getValidTriggerBuilder()
351                         .setAggregatableFilteringIdMaxBytes(2)
352                         .build());
353         assertThat(
354                         TriggerFixture.getValidTriggerBuilder()
355                                 .setAggregateDebugReportingString(
356                                         "{\"budget\":1024,\"key_piece\":\"0x1\"}")
357                                 .build())
358                 .isNotEqualTo(
359                         TriggerFixture.getValidTriggerBuilder()
360                                 .setAggregateDebugReportingString(
361                                         "{\"budget\":1024,\"key_piece\":\"0x2\"}")
362                                 .build());
363     }
364 
365     @Test
testHashCode_equals()366     public void testHashCode_equals() {
367         final Trigger trigger1 = TriggerFixture.getValidTriggerBuilder().build();
368         final Trigger trigger2 = TriggerFixture.getValidTriggerBuilder().build();
369         final Set<Trigger> triggerSet1 = Set.of(trigger1);
370         final Set<Trigger> triggerSet2 = Set.of(trigger2);
371         assertEquals(trigger1.hashCode(), trigger2.hashCode());
372         assertEquals(trigger1, trigger2);
373         assertEquals(triggerSet1, triggerSet2);
374     }
375 
376     @Test
testHashCode_notEquals()377     public void testHashCode_notEquals() {
378         final Trigger trigger1 = TriggerFixture.getValidTriggerBuilder().build();
379         final Trigger trigger2 = TriggerFixture.getValidTriggerBuilder().setId("100").build();
380         final Set<Trigger> triggerSet1 = Set.of(trigger1);
381         final Set<Trigger> triggerSet2 = Set.of(trigger2);
382         assertNotEquals(trigger1.hashCode(), trigger2.hashCode());
383         assertNotEquals(trigger1, trigger2);
384         assertNotEquals(triggerSet1, triggerSet2);
385         assertNotEquals(
386                 trigger1,
387                 TriggerFixture.getValidTriggerBuilder().setAttributionScopesString("5").build());
388     }
389 
390     @Test
testTriggerBuilder_validateArgumentAttributionDestination()391     public void testTriggerBuilder_validateArgumentAttributionDestination() {
392         assertInvalidTriggerArguments(
393                 null,
394                 TriggerFixture.ValidTriggerParams.ENROLLMENT_ID,
395                 TriggerFixture.ValidTriggerParams.REGISTRANT,
396                 TriggerFixture.ValidTriggerParams.TRIGGER_TIME,
397                 TriggerFixture.ValidTriggerParams.EVENT_TRIGGERS,
398                 TriggerFixture.ValidTriggerParams.AGGREGATE_TRIGGER_DATA,
399                 TriggerFixture.ValidTriggerParams.AGGREGATE_VALUES_STRING,
400                 TriggerFixture.ValidTriggerParams.TOP_LEVEL_FILTERS_JSON_STRING,
401                 TriggerFixture.ValidTriggerParams.TOP_LEVEL_NOT_FILTERS_JSON_STRING,
402                 TriggerFixture.ValidTriggerParams.DEBUG_KEY,
403                 TriggerFixture.ValidTriggerParams.ATTRIBUTION_CONFIGS_STRING,
404                 TriggerFixture.ValidTriggerParams.X_NETWORK_KEY_MAPPING,
405                 TriggerFixture.ValidTriggerParams.REGISTRATION_ORIGIN,
406                 TriggerFixture.ValidTriggerParams.AGGREGATABLE_SOURCE_REGISTRATION_TIME_CONFIG);
407         assertInvalidTriggerArguments(
408                 Uri.parse("com.destination"),
409                 TriggerFixture.ValidTriggerParams.ENROLLMENT_ID,
410                 TriggerFixture.ValidTriggerParams.REGISTRANT,
411                 TriggerFixture.ValidTriggerParams.TRIGGER_TIME,
412                 TriggerFixture.ValidTriggerParams.EVENT_TRIGGERS,
413                 TriggerFixture.ValidTriggerParams.AGGREGATE_TRIGGER_DATA,
414                 TriggerFixture.ValidTriggerParams.AGGREGATE_VALUES_STRING,
415                 TriggerFixture.ValidTriggerParams.TOP_LEVEL_FILTERS_JSON_STRING,
416                 TriggerFixture.ValidTriggerParams.TOP_LEVEL_NOT_FILTERS_JSON_STRING,
417                 TriggerFixture.ValidTriggerParams.DEBUG_KEY,
418                 TriggerFixture.ValidTriggerParams.ATTRIBUTION_CONFIGS_STRING,
419                 TriggerFixture.ValidTriggerParams.X_NETWORK_KEY_MAPPING,
420                 TriggerFixture.ValidTriggerParams.REGISTRATION_ORIGIN,
421                 TriggerFixture.ValidTriggerParams.AGGREGATABLE_SOURCE_REGISTRATION_TIME_CONFIG);
422     }
423 
424     @Test
testTriggerBuilder_validateArgumentEnrollmentId()425     public void testTriggerBuilder_validateArgumentEnrollmentId() {
426         assertInvalidTriggerArguments(
427                 TriggerFixture.ValidTriggerParams.ATTRIBUTION_DESTINATION,
428                 null,
429                 TriggerFixture.ValidTriggerParams.REGISTRANT,
430                 TriggerFixture.ValidTriggerParams.TRIGGER_TIME,
431                 TriggerFixture.ValidTriggerParams.EVENT_TRIGGERS,
432                 TriggerFixture.ValidTriggerParams.AGGREGATE_TRIGGER_DATA,
433                 TriggerFixture.ValidTriggerParams.AGGREGATE_VALUES_STRING,
434                 TriggerFixture.ValidTriggerParams.TOP_LEVEL_FILTERS_JSON_STRING,
435                 TriggerFixture.ValidTriggerParams.TOP_LEVEL_NOT_FILTERS_JSON_STRING,
436                 TriggerFixture.ValidTriggerParams.DEBUG_KEY,
437                 TriggerFixture.ValidTriggerParams.ATTRIBUTION_CONFIGS_STRING,
438                 TriggerFixture.ValidTriggerParams.X_NETWORK_KEY_MAPPING,
439                 TriggerFixture.ValidTriggerParams.REGISTRATION_ORIGIN,
440                 TriggerFixture.ValidTriggerParams.AGGREGATABLE_SOURCE_REGISTRATION_TIME_CONFIG);
441     }
442 
443     @Test
testTriggerBuilder_validateArgumentRegistrant()444     public void testTriggerBuilder_validateArgumentRegistrant() {
445         assertInvalidTriggerArguments(
446                 TriggerFixture.ValidTriggerParams.ATTRIBUTION_DESTINATION,
447                 TriggerFixture.ValidTriggerParams.ENROLLMENT_ID,
448                 null,
449                 TriggerFixture.ValidTriggerParams.TRIGGER_TIME,
450                 TriggerFixture.ValidTriggerParams.EVENT_TRIGGERS,
451                 TriggerFixture.ValidTriggerParams.AGGREGATE_TRIGGER_DATA,
452                 TriggerFixture.ValidTriggerParams.AGGREGATE_VALUES_STRING,
453                 TriggerFixture.ValidTriggerParams.TOP_LEVEL_FILTERS_JSON_STRING,
454                 TriggerFixture.ValidTriggerParams.TOP_LEVEL_NOT_FILTERS_JSON_STRING,
455                 TriggerFixture.ValidTriggerParams.DEBUG_KEY,
456                 TriggerFixture.ValidTriggerParams.ATTRIBUTION_CONFIGS_STRING,
457                 TriggerFixture.ValidTriggerParams.X_NETWORK_KEY_MAPPING,
458                 TriggerFixture.ValidTriggerParams.REGISTRATION_ORIGIN,
459                 TriggerFixture.ValidTriggerParams.AGGREGATABLE_SOURCE_REGISTRATION_TIME_CONFIG);
460         assertInvalidTriggerArguments(
461                 TriggerFixture.ValidTriggerParams.ATTRIBUTION_DESTINATION,
462                 TriggerFixture.ValidTriggerParams.ENROLLMENT_ID,
463                 Uri.parse("com.registrant"),
464                 TriggerFixture.ValidTriggerParams.TRIGGER_TIME,
465                 TriggerFixture.ValidTriggerParams.EVENT_TRIGGERS,
466                 TriggerFixture.ValidTriggerParams.AGGREGATE_TRIGGER_DATA,
467                 TriggerFixture.ValidTriggerParams.AGGREGATE_VALUES_STRING,
468                 TriggerFixture.ValidTriggerParams.TOP_LEVEL_FILTERS_JSON_STRING,
469                 TriggerFixture.ValidTriggerParams.TOP_LEVEL_NOT_FILTERS_JSON_STRING,
470                 TriggerFixture.ValidTriggerParams.DEBUG_KEY,
471                 TriggerFixture.ValidTriggerParams.ATTRIBUTION_CONFIGS_STRING,
472                 TriggerFixture.ValidTriggerParams.X_NETWORK_KEY_MAPPING,
473                 TriggerFixture.ValidTriggerParams.REGISTRATION_ORIGIN,
474                 TriggerFixture.ValidTriggerParams.AGGREGATABLE_SOURCE_REGISTRATION_TIME_CONFIG);
475     }
476 
477     @Test
testTriggerBuilder_validateArgumentRegistrationOrigin()478     public void testTriggerBuilder_validateArgumentRegistrationOrigin() {
479         assertInvalidTriggerArguments(
480                 TriggerFixture.ValidTriggerParams.ATTRIBUTION_DESTINATION,
481                 TriggerFixture.ValidTriggerParams.ENROLLMENT_ID,
482                 TriggerFixture.ValidTriggerParams.REGISTRANT,
483                 TriggerFixture.ValidTriggerParams.TRIGGER_TIME,
484                 TriggerFixture.ValidTriggerParams.EVENT_TRIGGERS,
485                 TriggerFixture.ValidTriggerParams.AGGREGATE_TRIGGER_DATA,
486                 TriggerFixture.ValidTriggerParams.AGGREGATE_VALUES_STRING,
487                 TriggerFixture.ValidTriggerParams.TOP_LEVEL_FILTERS_JSON_STRING,
488                 TriggerFixture.ValidTriggerParams.TOP_LEVEL_NOT_FILTERS_JSON_STRING,
489                 TriggerFixture.ValidTriggerParams.DEBUG_KEY,
490                 TriggerFixture.ValidTriggerParams.ATTRIBUTION_CONFIGS_STRING,
491                 TriggerFixture.ValidTriggerParams.X_NETWORK_KEY_MAPPING,
492                 null,
493                 TriggerFixture.ValidTriggerParams.AGGREGATABLE_SOURCE_REGISTRATION_TIME_CONFIG);
494     }
495 
496     @Test
testTriggerBuilder_validateArgumentSourceRegistrationTimeConfig()497     public void testTriggerBuilder_validateArgumentSourceRegistrationTimeConfig() {
498         assertInvalidTriggerArguments(
499                 TriggerFixture.ValidTriggerParams.ATTRIBUTION_DESTINATION,
500                 TriggerFixture.ValidTriggerParams.ENROLLMENT_ID,
501                 TriggerFixture.ValidTriggerParams.REGISTRANT,
502                 TriggerFixture.ValidTriggerParams.TRIGGER_TIME,
503                 TriggerFixture.ValidTriggerParams.EVENT_TRIGGERS,
504                 TriggerFixture.ValidTriggerParams.AGGREGATE_TRIGGER_DATA,
505                 TriggerFixture.ValidTriggerParams.AGGREGATE_VALUES_STRING,
506                 TriggerFixture.ValidTriggerParams.TOP_LEVEL_FILTERS_JSON_STRING,
507                 TriggerFixture.ValidTriggerParams.TOP_LEVEL_NOT_FILTERS_JSON_STRING,
508                 TriggerFixture.ValidTriggerParams.DEBUG_KEY,
509                 TriggerFixture.ValidTriggerParams.ATTRIBUTION_CONFIGS_STRING,
510                 TriggerFixture.ValidTriggerParams.X_NETWORK_KEY_MAPPING,
511                 TriggerFixture.ValidTriggerParams.REGISTRATION_ORIGIN,
512                 null);
513     }
514 
515     @Test
testAggregatableAttributionTrigger()516     public void testAggregatableAttributionTrigger() throws Exception {
517         when(mFlags.getMeasurementEnableAggregateValueFilters()).thenReturn(true, false);
518         AggregatableKeyValue value = new AggregatableKeyValue.Builder(93).build();
519         final Map<String, AggregatableKeyValue> values = Map.of("foo", value);
520         final AggregatableValuesConfig aggregatableValuesConfig =
521                 new AggregatableValuesConfig.Builder(values).build();
522         final List<AggregateTriggerData> triggerData =
523                 List.of(new AggregateTriggerData.Builder().build());
524         final AggregatableAttributionTrigger attributionTrigger =
525                 new AggregatableAttributionTrigger.Builder()
526                         .setValueConfigs(List.of(aggregatableValuesConfig))
527                         .setTriggerData(triggerData)
528                         .build();
529 
530         final Trigger trigger =
531                 TriggerFixture.getValidTriggerBuilder()
532                         .setAggregatableAttributionTrigger(attributionTrigger)
533                         .build();
534 
535         Optional<AggregatableAttributionTrigger> aggregatableAttributionTrigger =
536                 trigger.getAggregatableAttributionTrigger(mFlags);
537         assertTrue(aggregatableAttributionTrigger.isPresent());
538         assertNotNull(aggregatableAttributionTrigger.get().getTriggerData());
539         assertEquals(
540                 values.get("foo").getValue(),
541                 aggregatableAttributionTrigger
542                         .get()
543                         .getValueConfigs()
544                         .get(0)
545                         .getValues()
546                         .get("foo")
547                         .getValue());
548         assertEquals(triggerData, aggregatableAttributionTrigger.get().getTriggerData());
549     }
550 
551     @Test
testParseAggregateTrigger()552     public void testParseAggregateTrigger() throws JSONException {
553         when(mFlags.getMeasurementEnableAggregateValueFilters()).thenReturn(true, false);
554         when(mFlags.getMeasurementEnableAggregatableNamedBudgets()).thenReturn(true);
555         JSONArray triggerDatas = new JSONArray();
556         JSONObject jsonObject1 = new JSONObject();
557         jsonObject1.put("key_piece", "0x400");
558         jsonObject1.put("source_keys", new JSONArray(Arrays.asList("campaignCounts")));
559         jsonObject1.put("filters", createFilterJSONArray());
560         jsonObject1.put("not_filters", createFilterJSONArray());
561         jsonObject1.put("x_network_data", createXNetworkDataJSONObject());
562         JSONObject jsonObject2 = new JSONObject();
563         jsonObject2.put("key_piece", "0xA80");
564         jsonObject2.put("source_keys", new JSONArray(Arrays.asList("geoValue", "noMatch")));
565         jsonObject1.put("x_network_data", createXNetworkDataJSONObject());
566         triggerDatas.put(jsonObject1);
567         triggerDatas.put(jsonObject2);
568 
569         JSONObject values = new JSONObject();
570         values.put("campaignCounts", 32768);
571         values.put("geoValue", 1664);
572 
573         JSONArray aggregateDedupKeys = new JSONArray();
574         JSONObject dedupKeyJsonObject1 = new JSONObject();
575         dedupKeyJsonObject1.put("deduplication_key", "10");
576         dedupKeyJsonObject1.put("filters", createFilterJSONArray());
577         dedupKeyJsonObject1.put("not_filters", createFilterJSONArray());
578         JSONObject dedupKeyJsonObject2 = new JSONObject();
579         dedupKeyJsonObject2.put("deduplication_key", "11");
580         dedupKeyJsonObject2.put("filters", createFilterJSONArray());
581         dedupKeyJsonObject2.put("not_filters", createFilterJSONArray());
582         JSONObject dedupKeyJsonObject3 = new JSONObject();
583         dedupKeyJsonObject3.put("filters", createFilterJSONArray());
584         dedupKeyJsonObject3.put("not_filters", createFilterJSONArray());
585         aggregateDedupKeys.put(dedupKeyJsonObject1);
586         aggregateDedupKeys.put(dedupKeyJsonObject2);
587         aggregateDedupKeys.put(dedupKeyJsonObject3);
588 
589         JSONArray namedBudgets = new JSONArray();
590         JSONObject budgetJsonObject1 = new JSONObject();
591         budgetJsonObject1.put("name", "biddable");
592         budgetJsonObject1.put("filters", createFilterJSONArray());
593         budgetJsonObject1.put("not_filters", createFilterJSONArray());
594         JSONObject budgetJsonObject2 = new JSONObject();
595         budgetJsonObject2.put("name", "nonbiddable");
596         budgetJsonObject2.put("filters", createFilterJSONArray());
597         budgetJsonObject2.put("not_filters", createFilterJSONArray());
598         namedBudgets.put(budgetJsonObject1);
599         namedBudgets.put(budgetJsonObject2);
600 
601         Trigger trigger =
602                 TriggerFixture.getValidTriggerBuilder()
603                         .setAggregateTriggerData(triggerDatas.toString())
604                         .setAggregateValuesString(values.toString())
605                         .setAggregateDeduplicationKeys(aggregateDedupKeys.toString())
606                         .setNamedBudgetsString(namedBudgets.toString())
607                         .build();
608         Optional<AggregatableAttributionTrigger> aggregatableAttributionTrigger =
609                 trigger.getAggregatableAttributionTrigger(mFlags);
610 
611         assertTrue(aggregatableAttributionTrigger.isPresent());
612         AggregatableAttributionTrigger aggregateTrigger = aggregatableAttributionTrigger.get();
613         assertEquals(aggregateTrigger.getTriggerData().size(), 2);
614         assertEquals(aggregateTrigger.getTriggerData().get(0).getSourceKeys().size(), 1);
615         assertEquals(aggregateTrigger.getTriggerData().get(0).getKey().intValue(), 1024);
616         assertTrue(aggregateTrigger.getTriggerData().get(0)
617                 .getSourceKeys().contains("campaignCounts"));
618         assertTrue(aggregateTrigger.getTriggerData().get(0).getFilterSet().isPresent());
619         assertEquals(aggregateTrigger.getTriggerData().get(0).getFilterSet().get()
620                 .get(0).getAttributionFilterMap().size(), 2);
621         assertTrue(aggregateTrigger.getTriggerData().get(0).getNotFilterSet().isPresent());
622         assertEquals(aggregateTrigger.getTriggerData().get(0).getNotFilterSet().get()
623                 .get(0).getAttributionFilterMap().size(), 2);
624         assertEquals(
625                 aggregateTrigger
626                         .getTriggerData()
627                         .get(0)
628                         .getXNetworkData()
629                         .get()
630                         .getKeyOffset()
631                         .get()
632                         .getValue()
633                         .longValue(),
634                 10L);
635         assertEquals(aggregateTrigger.getTriggerData().get(1).getKey().intValue(), 2688);
636         assertEquals(aggregateTrigger.getTriggerData().get(1).getSourceKeys().size(), 2);
637         assertTrue(aggregateTrigger.getTriggerData().get(1).getSourceKeys().contains("geoValue"));
638         assertTrue(aggregateTrigger.getTriggerData().get(1).getSourceKeys().contains("noMatch"));
639         assertThat(aggregateTrigger.getValueConfigs().size()).isEqualTo(1);
640         assertThat(
641                         aggregateTrigger
642                                 .getValueConfigs()
643                                 .get(0)
644                                 .getValues()
645                                 .get("campaignCounts")
646                                 .getValue())
647                 .isEqualTo(32768);
648         assertThat(aggregateTrigger.getValueConfigs().get(0).getValues().get("geoValue").getValue())
649                 .isEqualTo(1664);
650         assertEquals(
651                 aggregateTrigger
652                         .getTriggerData()
653                         .get(0)
654                         .getXNetworkData()
655                         .get()
656                         .getKeyOffset()
657                         .get()
658                         .getValue()
659                         .longValue(),
660                 10L);
661         assertTrue(aggregateTrigger.getAggregateDeduplicationKeys().isPresent());
662         assertEquals(aggregateTrigger.getAggregateDeduplicationKeys().get().size(), 3);
663         assertTrue(
664                 aggregateTrigger
665                         .getAggregateDeduplicationKeys()
666                         .get()
667                         .get(0)
668                         .getDeduplicationKey()
669                         .isPresent());
670         assertEquals(
671                 aggregateTrigger
672                         .getAggregateDeduplicationKeys()
673                         .get()
674                         .get(0)
675                         .getDeduplicationKey()
676                         .get(),
677                 new UnsignedLong(10L));
678         assertTrue(
679                 aggregateTrigger
680                         .getAggregateDeduplicationKeys()
681                         .get()
682                         .get(0)
683                         .getFilterSet()
684                         .isPresent());
685         assertEquals(
686                 aggregateTrigger
687                         .getAggregateDeduplicationKeys()
688                         .get()
689                         .get(0)
690                         .getFilterSet()
691                         .get()
692                         .get(0)
693                         .getAttributionFilterMap()
694                         .size(),
695                 2);
696         assertTrue(
697                 aggregateTrigger
698                         .getAggregateDeduplicationKeys()
699                         .get()
700                         .get(0)
701                         .getNotFilterSet()
702                         .isPresent());
703         assertEquals(
704                 aggregateTrigger
705                         .getAggregateDeduplicationKeys()
706                         .get()
707                         .get(0)
708                         .getNotFilterSet()
709                         .get()
710                         .get(0)
711                         .getAttributionFilterMap()
712                         .size(),
713                 2);
714 
715         assertTrue(
716                 aggregateTrigger
717                         .getAggregateDeduplicationKeys()
718                         .get()
719                         .get(1)
720                         .getFilterSet()
721                         .isPresent());
722         assertEquals(
723                 aggregateTrigger
724                         .getAggregateDeduplicationKeys()
725                         .get()
726                         .get(1)
727                         .getFilterSet()
728                         .get()
729                         .get(0)
730                         .getAttributionFilterMap()
731                         .size(),
732                 2);
733         assertTrue(
734                 aggregateTrigger
735                         .getAggregateDeduplicationKeys()
736                         .get()
737                         .get(1)
738                         .getNotFilterSet()
739                         .isPresent());
740         assertEquals(
741                 aggregateTrigger
742                         .getAggregateDeduplicationKeys()
743                         .get()
744                         .get(1)
745                         .getNotFilterSet()
746                         .get()
747                         .get(0)
748                         .getAttributionFilterMap()
749                         .size(),
750                 2);
751         assertEquals(
752                 aggregateTrigger
753                         .getAggregateDeduplicationKeys()
754                         .get()
755                         .get(1)
756                         .getDeduplicationKey()
757                         .get(),
758                 new UnsignedLong(11L));
759 
760         assertTrue(
761                 aggregateTrigger
762                         .getAggregateDeduplicationKeys()
763                         .get()
764                         .get(2)
765                         .getFilterSet()
766                         .isPresent());
767         assertEquals(
768                 aggregateTrigger
769                         .getAggregateDeduplicationKeys()
770                         .get()
771                         .get(2)
772                         .getFilterSet()
773                         .get()
774                         .get(0)
775                         .getAttributionFilterMap()
776                         .size(),
777                 2);
778         assertTrue(
779                 aggregateTrigger
780                         .getAggregateDeduplicationKeys()
781                         .get()
782                         .get(2)
783                         .getNotFilterSet()
784                         .isPresent());
785         assertEquals(
786                 aggregateTrigger
787                         .getAggregateDeduplicationKeys()
788                         .get()
789                         .get(2)
790                         .getNotFilterSet()
791                         .get()
792                         .get(0)
793                         .getAttributionFilterMap()
794                         .size(),
795                 2);
796         assertTrue(
797                 aggregateTrigger
798                         .getAggregateDeduplicationKeys()
799                         .get()
800                         .get(2)
801                         .getDeduplicationKey()
802                         .isEmpty());
803 
804         assertThat(aggregateTrigger.getNamedBudgets()).isNotNull();
805         assertThat(aggregateTrigger.getNamedBudgets().size()).isEqualTo(2);
806         assertThat(aggregateTrigger.getNamedBudgets().get(0).getName()).isEqualTo("biddable");
807         assertThat(aggregateTrigger.getNamedBudgets().get(0).getFilterSet()).isNotNull();
808         assertThat(
809                         aggregateTrigger
810                                 .getNamedBudgets()
811                                 .get(0)
812                                 .getFilterSet()
813                                 .get(0)
814                                 .getAttributionFilterMap()
815                                 .size())
816                 .isEqualTo(2);
817         assertThat(aggregateTrigger.getNamedBudgets().get(0).getNotFilterSet()).isNotNull();
818         assertThat(
819                         aggregateTrigger
820                                 .getNamedBudgets()
821                                 .get(0)
822                                 .getNotFilterSet()
823                                 .get(0)
824                                 .getAttributionFilterMap()
825                                 .size())
826                 .isEqualTo(2);
827         assertThat(aggregateTrigger.getNamedBudgets().get(1).getFilterSet()).isNotNull();
828         assertThat(
829                         aggregateTrigger
830                                 .getNamedBudgets()
831                                 .get(1)
832                                 .getFilterSet()
833                                 .get(0)
834                                 .getAttributionFilterMap()
835                                 .size())
836                 .isEqualTo(2);
837         assertThat(aggregateTrigger.getNamedBudgets().get(1).getNotFilterSet()).isNotNull();
838         assertThat(
839                         aggregateTrigger
840                                 .getNamedBudgets()
841                                 .get(1)
842                                 .getNotFilterSet()
843                                 .get(0)
844                                 .getAttributionFilterMap()
845                                 .size())
846                 .isEqualTo(2);
847         assertThat(aggregateTrigger.getNamedBudgets().get(1).getName()).isEqualTo("nonbiddable");
848     }
849 
850     @Test
testParseAggregateTrigger_noNamedBudgets()851     public void testParseAggregateTrigger_noNamedBudgets() throws JSONException {
852         when(mFlags.getMeasurementEnableAggregateValueFilters()).thenReturn(true, false);
853         when(mFlags.getMeasurementEnableAggregatableNamedBudgets()).thenReturn(true);
854         JSONArray triggerDatas = new JSONArray();
855         JSONObject jsonObject1 = new JSONObject();
856         jsonObject1.put("key_piece", "0x400");
857         jsonObject1.put("source_keys", new JSONArray(Arrays.asList("campaignCounts")));
858         jsonObject1.put("filters", createFilterJSONArray());
859         jsonObject1.put("not_filters", createFilterJSONArray());
860         jsonObject1.put("x_network_data", createXNetworkDataJSONObject());
861         JSONObject jsonObject2 = new JSONObject();
862         jsonObject2.put("key_piece", "0xA80");
863         jsonObject2.put("source_keys", new JSONArray(Arrays.asList("geoValue", "noMatch")));
864         jsonObject1.put("x_network_data", createXNetworkDataJSONObject());
865         triggerDatas.put(jsonObject1);
866         triggerDatas.put(jsonObject2);
867 
868         JSONObject values = new JSONObject();
869         values.put("campaignCounts", 32768);
870         values.put("geoValue", 1664);
871 
872         Trigger trigger =
873                 TriggerFixture.getValidTriggerBuilder()
874                         .setAggregateTriggerData(triggerDatas.toString())
875                         .setAggregateValuesString(values.toString())
876                         .build();
877         Optional<AggregatableAttributionTrigger> aggregatableAttributionTrigger =
878                 trigger.getAggregatableAttributionTrigger(mFlags);
879 
880         assertThat(aggregatableAttributionTrigger).isPresent();
881         AggregatableAttributionTrigger aggregateTrigger = aggregatableAttributionTrigger.get();
882 
883         assertThat(aggregateTrigger.getNamedBudgets()).isNull();
884     }
885 
886     @Test
testGetAttributionDestinationBaseUri_appDestination()887     public void testGetAttributionDestinationBaseUri_appDestination() {
888         Trigger trigger = TriggerFixture.getValidTriggerBuilder()
889                 .setAttributionDestination(APP_DESTINATION)
890                 .setDestinationType(EventSurfaceType.APP)
891                 .build();
892         assertEquals(APP_DESTINATION, trigger.getAttributionDestinationBaseUri());
893     }
894 
895     @Test
testGetAttributionDestinationBaseUri_webDestination()896     public void testGetAttributionDestinationBaseUri_webDestination() {
897         Trigger trigger = TriggerFixture.getValidTriggerBuilder()
898                 .setAttributionDestination(WEB_DESTINATION)
899                 .setDestinationType(EventSurfaceType.WEB)
900                 .build();
901         assertEquals(WEB_DESTINATION, trigger.getAttributionDestinationBaseUri());
902     }
903 
904     @Test
testGetAttributionDestinationBaseUri_trimsWebDestinationWithSubdomain()905     public void testGetAttributionDestinationBaseUri_trimsWebDestinationWithSubdomain() {
906         Trigger trigger = TriggerFixture.getValidTriggerBuilder()
907                 .setAttributionDestination(WEB_DESTINATION_WITH_SUBDOMAIN)
908                 .setDestinationType(EventSurfaceType.WEB)
909                 .build();
910         assertEquals(WEB_DESTINATION, trigger.getAttributionDestinationBaseUri());
911     }
912 
913     @Test
testGetAttributionDestinationBaseUri_trimsWebDestinationWithPath()914     public void testGetAttributionDestinationBaseUri_trimsWebDestinationWithPath() {
915         Trigger trigger = TriggerFixture.getValidTriggerBuilder()
916                 .setAttributionDestination(WEB_DESTINATION_WITH_PATH)
917                 .setDestinationType(EventSurfaceType.WEB)
918                 .build();
919         assertEquals(WEB_DESTINATION, trigger.getAttributionDestinationBaseUri());
920     }
921 
922     @Test
923     public void
testGetAttributionDestinationBaseUri_trimsWebDestinationWithSubdomainPathQueryFrag()924             testGetAttributionDestinationBaseUri_trimsWebDestinationWithSubdomainPathQueryFrag() {
925         Trigger trigger = TriggerFixture.getValidTriggerBuilder()
926                 .setAttributionDestination(WEB_DESTINATION_WITH_SUBDOMAIN_PATH_QUERY_FRAGMENT)
927                 .setDestinationType(EventSurfaceType.WEB)
928                 .build();
929         assertEquals(WEB_DESTINATION, trigger.getAttributionDestinationBaseUri());
930     }
931 
932     @Test
testGetAttributionDestinationBaseUri_invalidWebDestination()933     public void testGetAttributionDestinationBaseUri_invalidWebDestination() {
934         Trigger trigger = TriggerFixture.getValidTriggerBuilder()
935                 .setAttributionDestination(WEB_DESTINATION_INVALID)
936                 .setDestinationType(EventSurfaceType.WEB)
937                 .build();
938         assertNull(trigger.getAttributionDestinationBaseUri());
939     }
940 
941     @Test
parseEventTriggers_handlesValueField()942     public void parseEventTriggers_handlesValueField() throws JSONException {
943         // setup
944         JSONObject filtersMap1 =
945                 new JSONObject(
946                         "{\n"
947                                 + "    \"filter_key_1\": [\"filter_value_1\"], \n"
948                                 + "    \"filter_key_2\": [\"filter_value_2\"] \n"
949                                 + "   }");
950         JSONObject notFiltersMap1 =
951                 new JSONObject(
952                         "{\n"
953                                 + "    \"not_filter_key_1\": [\"not_filter_value_1\", "
954                                 + "\"not_filter_value_2\"]"
955                                 + "   }");
956         JSONObject notFiltersMap2 =
957                 new JSONObject("{\n" + "    \"key_1\": [\"value_1_x\"] \n" + "   }");
958 
959         Trigger trigger =
960                 TriggerFixture.getValidTriggerBuilder()
961                         .setId("triggerId1")
962                         .setStatus(Trigger.Status.PENDING)
963                         .setEventTriggers(
964                                 "[\n"
965                                         + "{\n"
966                                         + "  \"trigger_data\": \"2\",\n"
967                                         + "  \"priority\": \"2\",\n"
968                                         + "  \"value\": \"100\",\n"
969                                         + "  \"deduplication_key\": \"2\",\n"
970                                         + "  \"filters\": [{\n"
971                                         + "    \"filter_key_1\": [\"filter_value_1\"], \n"
972                                         + "    \"filter_key_2\": [\"filter_value_2\"] \n"
973                                         + "   }],\n"
974                                         + "  \"not_filters\": [{\n"
975                                         + "    \"not_filter_key_1\": [\"not_filter_value_1\", "
976                                         + "\"not_filter_value_2\"]"
977                                         + "   }]\n"
978                                         + "},"
979                                         + "{\n"
980                                         + "  \"trigger_data\": \"3\",\n"
981                                         + "  \"priority\": \"3\",\n"
982                                         + "  \"value\": \"120\",\n"
983                                         + "  \"deduplication_key\": \"3\",\n"
984                                         + "  \"not_filters\": [{\n"
985                                         + "    \"key_1\": [\"value_1_x\"] \n"
986                                         + "   }]\n"
987                                         + "}"
988                                         + "]\n")
989                         .setTriggerTime(234324L)
990                         .build();
991         EventTrigger eventTrigger1 =
992                 new EventTrigger.Builder(new UnsignedLong(2L))
993                         .setTriggerPriority(2L)
994                         .setTriggerValue(100L)
995                         .setDedupKey(new UnsignedLong(2L))
996                         .setFilterSet(
997                                 List.of(
998                                         new FilterMap.Builder()
999                                                 .buildFilterData(filtersMap1)
1000                                                 .build()))
1001                         .setNotFilterSet(
1002                                 List.of(
1003                                         new FilterMap.Builder()
1004                                                 .buildFilterData(notFiltersMap1)
1005                                                 .build()))
1006                         .build();
1007         EventTrigger eventTrigger2 =
1008                 new EventTrigger.Builder(new UnsignedLong(3L))
1009                         .setTriggerPriority(3L)
1010                         .setTriggerValue(120L)
1011                         .setDedupKey(new UnsignedLong(3L))
1012                         .setNotFilterSet(
1013                                 List.of(
1014                                         new FilterMap.Builder()
1015                                                 .buildFilterData(notFiltersMap2)
1016                                                 .build()))
1017                         .build();
1018 
1019         when(mFlags.getMeasurementFlexibleEventReportingApiEnabled()).thenReturn(true);
1020 
1021         // Action
1022         List<EventTrigger> actualEventTriggers = trigger.parseEventTriggers(mFlags);
1023 
1024         // Assertion
1025         assertEquals(Arrays.asList(eventTrigger1, eventTrigger2), actualEventTriggers);
1026     }
1027 
1028     @Test
parseAdtechBitMapping_nonEmpty_parseSuccess()1029     public void parseAdtechBitMapping_nonEmpty_parseSuccess() throws JSONException {
1030         Trigger trigger =
1031                 TriggerFixture.getValidTriggerBuilder()
1032                         .setId("triggerId1")
1033                         .setStatus(Trigger.Status.PENDING)
1034                         .setAdtechBitMapping(
1035                                 "{\"AdTechA-enrollment_id\": \"0x1\","
1036                                         + "\"AdTechB-enrollment_id\": \"0x2\"}")
1037                         .build();
1038 
1039         Map<String, BigInteger> adtechMapping = trigger.parseAdtechKeyMapping();
1040         assertEquals(adtechMapping.size(), 2);
1041         BigInteger adtechBit1 = new BigInteger("1", 16);
1042         BigInteger adtechBit2 = new BigInteger("2", 16);
1043         assertEquals(adtechMapping.get("AdTechA-enrollment_id"), adtechBit1);
1044         assertEquals(adtechMapping.get("AdTechB-enrollment_id"), adtechBit2);
1045     }
1046 
1047     @Test
getAttributionScopes_validJsonStringArray_parseSuccess()1048     public void getAttributionScopes_validJsonStringArray_parseSuccess() throws JSONException {
1049         Trigger trigger =
1050                 TriggerFixture.getValidTriggerBuilder()
1051                         .setId("triggerId1")
1052                         .setAttributionScopesString("[\"1\", \"2\"]")
1053                         .build();
1054         assertThat(trigger.getAttributionScopes()).containsExactly("1", "2");
1055     }
1056 
1057     @Test
testParseAggregateTrigger_anyUnsupportedAggValuesJsonObject_throwsException()1058     public void testParseAggregateTrigger_anyUnsupportedAggValuesJsonObject_throwsException() {
1059         String unsupportedAggregatableValues =
1060                 "{\"campaignCounts\": 32768, \"geoValue\":{\"value\": " + "1664}}";
1061         Trigger trigger =
1062                 TriggerFixture.getValidTriggerBuilder()
1063                         .setAggregateValuesString(unsupportedAggregatableValues)
1064                         .build();
1065         assertThrows(JSONException.class, () -> trigger.getAggregatableAttributionTrigger(mFlags));
1066     }
1067 
1068     @Test
testParseAggregateTrigger_anyUnsupportedAggValuesJsonArray_throwsException()1069     public void testParseAggregateTrigger_anyUnsupportedAggValuesJsonArray_throwsException() {
1070         when(mFlags.getMeasurementEnableAggregateValueFilters()).thenReturn(true);
1071         String unsupportedAggregatableValues =
1072                 "[ {\"values\":  {\"campaignCounts\": 32768, \"geoValue\":{\"value\": " + "1664}}";
1073         Trigger trigger =
1074                 TriggerFixture.getValidTriggerBuilder()
1075                         .setAggregateValuesString(unsupportedAggregatableValues)
1076                         .build();
1077         assertThrows(JSONException.class, () -> trigger.getAggregatableAttributionTrigger(mFlags));
1078     }
1079 
1080     @Test
testParseAggregateTrigger_aggValuesJsonObjectFlexibleFilterOn_passes()1081     public void testParseAggregateTrigger_aggValuesJsonObjectFlexibleFilterOn_passes()
1082             throws Exception {
1083         when(mFlags.getMeasurementEnableFlexibleContributionFiltering()).thenReturn(true);
1084         String validAggregatableValues =
1085                 "{\"campaignCounts\": {\"value\":32768, \"filtering_id\":\"255\"},"
1086                         + " \"geoValue\":1664}}";
1087         Trigger trigger =
1088                 TriggerFixture.getValidTriggerBuilder()
1089                         .setAggregateValuesString(validAggregatableValues)
1090                         .build();
1091         Optional<AggregatableAttributionTrigger> aggregatableAttributionTrigger =
1092                 trigger.getAggregatableAttributionTrigger(mFlags);
1093         assertThat(aggregatableAttributionTrigger).isNotNull();
1094         AggregatableValuesConfig config =
1095                 aggregatableAttributionTrigger.get().getValueConfigs().get(0);
1096         assertThat(config.getValues().keySet().size()).isEqualTo(2);
1097         assertThat(config.getValues().get("campaignCounts").getFilteringId())
1098                 .isEqualTo(new UnsignedLong("255"));
1099         assertThat(config.getValues().get("campaignCounts").getValue()).isEqualTo(32768);
1100         assertThat(config.getValues().get("geoValue").getValue()).isEqualTo(1664);
1101         assertThat(config.getValues().get("geoValue").getFilteringId())
1102                 .isEqualTo(UnsignedLong.ZERO);
1103     }
1104 
1105     @Test
testParseAggregateTrigger_aggValuesJsonArrayAggregateValueFiltersOff_returnsEmpty()1106     public void testParseAggregateTrigger_aggValuesJsonArrayAggregateValueFiltersOff_returnsEmpty()
1107             throws JSONException {
1108         String invalidAggregatableValues =
1109                 "[ {\"values\": {\"campaignCounts\": {\"value\": 1664}}} ]";
1110         // Aggregate Values in Trigger table is persisted in JSONArray string format.
1111         Trigger trigger =
1112                 TriggerFixture.getValidTriggerBuilder()
1113                         .setAggregateValuesString(invalidAggregatableValues)
1114                         .build();
1115         // Values are not parsable and trigger is rejected.
1116         assertThat(trigger.getAggregatableAttributionTrigger(mFlags)).isEqualTo(Optional.empty());
1117     }
1118 
1119     @Test
testParseAggregateTrigger_aggValuesJsonArrayFlexibleFilterAggUnsupported_throws()1120     public void testParseAggregateTrigger_aggValuesJsonArrayFlexibleFilterAggUnsupported_throws() {
1121         when(mFlags.getMeasurementEnableAggregateValueFilters()).thenReturn(true);
1122         String unsupportedAggregatableValues =
1123                 "[ {\"values\": {\"campaignCounts\": {\"value\": 1664}}} ]";
1124         Trigger trigger =
1125                 TriggerFixture.getValidTriggerBuilder()
1126                         .setAggregateValuesString(unsupportedAggregatableValues)
1127                         .build();
1128         assertThrows(JSONException.class, () -> trigger.getAggregatableAttributionTrigger(mFlags));
1129     }
1130 
1131     @Test
testParseAggregateTrigger_aggValuesJsonArrayAggregateValueFiltersOn_success()1132     public void testParseAggregateTrigger_aggValuesJsonArrayAggregateValueFiltersOn_success()
1133             throws Exception {
1134         when(mFlags.getMeasurementEnableAggregateValueFilters()).thenReturn(true);
1135         String validAggregatableValues =
1136                 "[{\"values\":{\"campaignCounts\":32768, \"geoValue\":1664}},{\"values\":{\"a\":1,"
1137                         + " \"b\":2, \"c\":3}}]";
1138         // Verify aggregatable values string gets parsed into AggregatableValuesConfig.
1139         Trigger trigger =
1140                 TriggerFixture.getValidTriggerBuilder()
1141                         .setAggregateValuesString(validAggregatableValues)
1142                         .build();
1143         Optional<AggregatableAttributionTrigger> aggregatableAttributionTrigger =
1144                 trigger.getAggregatableAttributionTrigger(mFlags);
1145         assertThat(aggregatableAttributionTrigger).isNotNull();
1146         assertThat(aggregatableAttributionTrigger.get().getValueConfigs().size())
1147                 .isEqualTo(2);
1148         assertThat(aggregatableAttributionTrigger.get().getValueConfigs().get(0).getValues().size())
1149                 .isEqualTo(2);
1150         assertThat(aggregatableAttributionTrigger.get().getValueConfigs().get(1).getValues().size())
1151                 .isEqualTo(3);
1152     }
1153 
1154     @Test
1155     public void
testParseAggregateTrigger_aggregateValuesJsonArrayFlagsEnabledWithFilteringId_passes()1156             testParseAggregateTrigger_aggregateValuesJsonArrayFlagsEnabledWithFilteringId_passes()
1157                     throws Exception {
1158         when(mFlags.getMeasurementEnableAggregateValueFilters()).thenReturn(true);
1159         when(mFlags.getMeasurementEnableFlexibleContributionFiltering()).thenReturn(true);
1160         String validAggregatableValues =
1161                 "[{\"values\":{\"campaignCounts\":{\"value\":32768,\"filtering_id\":\"123\"},"
1162                         + "\"geoValue\":1664}}]";
1163         Trigger trigger =
1164                 TriggerFixture.getValidTriggerBuilder()
1165                         .setAggregateValuesString(validAggregatableValues)
1166                         .build();
1167         Optional<AggregatableAttributionTrigger> aggregatableAttributionTrigger =
1168                 trigger.getAggregatableAttributionTrigger(mFlags);
1169         assertThat(aggregatableAttributionTrigger).isNotNull();
1170         AggregatableValuesConfig config =
1171                 aggregatableAttributionTrigger.get().getValueConfigs().get(0);
1172         assertThat(config.getValues().get("campaignCounts").getValue()).isEqualTo(32768);
1173         assertThat(config.getValues().get("campaignCounts").getFilteringId())
1174                 .isEqualTo(new UnsignedLong("123"));
1175         assertThat(config.getValues().get("geoValue").getValue()).isEqualTo(1664);
1176         assertThat(config.getValues().get("geoValue").getFilteringId())
1177                 .isEqualTo(UnsignedLong.ZERO);
1178     }
1179 
1180 
1181     @Test
aggregateDebugReport_parsing_asExpected()1182     public void aggregateDebugReport_parsing_asExpected() throws JSONException {
1183         // Setup
1184         String aggregateDebugReport =
1185                 "{\"key_piece\":\"0x222\","
1186                         + "\"debug_data\":["
1187                         + "{"
1188                         + "\"types\": [\"trigger-aggregate-insufficient-budget\", "
1189                         + "\"trigger-aggregate-deduplicated\"],"
1190                         + "\"key_piece\": \"0x333\","
1191                         + "\"value\": 333"
1192                         + "},"
1193                         + "{"
1194                         + "\"types\": [\"trigger-aggregate-report-window-passed\", "
1195                         + "\"trigger-event-low-priority\"],"
1196                         + "\"key_piece\": \"0x444\","
1197                         + "\"value\": 444"
1198                         + "},"
1199                         + "{"
1200                         + "\"types\": [\"unspecified\"],"
1201                         + "\"key_piece\": \"0x555\","
1202                         + "\"value\": 555"
1203                         + "}"
1204                         + "],"
1205                         + "\"aggregation_coordinator_origin\":\"https://aws.example\"}";
1206         Source source =
1207                 SourceFixture.getValidSourceBuilder()
1208                         .setAggregateDebugReportingString(aggregateDebugReport)
1209                         .build();
1210 
1211         // Execution
1212         AggregateDebugReportData debugData1 =
1213                 new AggregateDebugReportData.Builder(
1214                                 new HashSet<>(
1215                                         Arrays.asList(
1216                                                 DebugReportApi.Type
1217                                                         .TRIGGER_AGGREGATE_INSUFFICIENT_BUDGET
1218                                                         .getValue(),
1219                                                 DebugReportApi.Type.TRIGGER_AGGREGATE_DEDUPLICATED
1220                                                         .getValue())),
1221                                 new BigInteger("333", 16),
1222                                 333)
1223                         .build();
1224         AggregateDebugReportData debugData2 =
1225                 new AggregateDebugReportData.Builder(
1226                                 new HashSet<>(
1227                                         Arrays.asList(
1228                                                 DebugReportApi.Type
1229                                                         .TRIGGER_AGGREGATE_REPORT_WINDOW_PASSED
1230                                                         .getValue(),
1231                                                 DebugReportApi.Type.TRIGGER_EVENT_LOW_PRIORITY
1232                                                         .getValue())),
1233                                 new BigInteger("444", 16),
1234                                 444)
1235                         .build();
1236         AggregateDebugReportData debugData3 =
1237                 new AggregateDebugReportData.Builder(
1238                                 Collections.singleton(DebugReportApi.Type.UNSPECIFIED.getValue()),
1239                                 new BigInteger("555", 16),
1240                                 555)
1241                         .build();
1242 
1243         // Assertion
1244         assertThat(source.getAggregateDebugReportingObject())
1245                 .isEqualTo(
1246                         new AggregateDebugReporting.Builder(
1247                                         0,
1248                                         new BigInteger("222", 16),
1249                                         Arrays.asList(debugData1, debugData2, debugData3),
1250                                         Uri.parse("https://aws.example"))
1251                                 .build());
1252     }
1253 
1254     @Test
hasAggregatableData_aggregateValuesAndDataNonEmpty_success()1255     public void hasAggregatableData_aggregateValuesAndDataNonEmpty_success() throws JSONException {
1256         Trigger trigger =
1257                 TriggerFixture.getValidTriggerBuilder()
1258                         .setId("triggerId1")
1259                         .setAggregateTriggerData(ValidTriggerParams.AGGREGATE_TRIGGER_DATA)
1260                         .setAggregateValuesString(ValidTriggerParams.AGGREGATE_VALUES_STRING)
1261                         .build();
1262         assertThat(trigger.hasAggregatableData(mFlags)).isTrue();
1263     }
1264 
1265     @Test
hasAggregatableData_aggregateDataNonEmptyAggregateValuesEmptyArray_success()1266     public void hasAggregatableData_aggregateDataNonEmptyAggregateValuesEmptyArray_success()
1267             throws JSONException {
1268         when(mFlags.getMeasurementEnableAggregateValueFilters()).thenReturn(true);
1269         Trigger trigger =
1270                 TriggerFixture.getValidTriggerBuilder()
1271                         .setId("triggerId1")
1272                         .setAggregateValuesString("[]")
1273                         .setAggregateTriggerData(ValidTriggerParams.AGGREGATE_TRIGGER_DATA)
1274                         .build();
1275         assertThat(trigger.hasAggregatableData(mFlags)).isTrue();
1276     }
1277 
1278     @Test
hasAggregatableData_aggregateDataNonEmptyAggregateValuesEmptyObject_success()1279     public void hasAggregatableData_aggregateDataNonEmptyAggregateValuesEmptyObject_success()
1280             throws JSONException {
1281         Trigger trigger =
1282                 TriggerFixture.getValidTriggerBuilder()
1283                         .setId("triggerId1")
1284                         .setAggregateValuesString("{}")
1285                         .setAggregateTriggerData(ValidTriggerParams.AGGREGATE_TRIGGER_DATA)
1286                         .build();
1287         assertThat(trigger.hasAggregatableData(mFlags)).isTrue();
1288     }
1289 
1290     @Test
hasAggregatableData_aggregateValuesPresent_success()1291     public void hasAggregatableData_aggregateValuesPresent_success() throws JSONException {
1292         Trigger trigger =
1293                 TriggerFixture.getValidTriggerBuilder()
1294                         .setId("triggerId1")
1295                         .setAggregateValuesString(ValidTriggerParams.AGGREGATE_VALUES_STRING)
1296                         .setAggregateTriggerData("[]")
1297                         .build();
1298         assertThat(trigger.hasAggregatableData(mFlags)).isTrue();
1299     }
1300 
1301     @Test
hasAggregatableData_aggregateValuesAndDataNotPresent_fail()1302     public void hasAggregatableData_aggregateValuesAndDataNotPresent_fail() throws JSONException {
1303         Trigger trigger = TriggerFixture.getValidTriggerBuilder().setId("triggerId1").build();
1304         assertThat(trigger.hasAggregatableData(mFlags)).isFalse();
1305     }
1306 
1307     @Test
hasAggregatableData_aggregateValuesObjectAndDataEmpty_fail()1308     public void hasAggregatableData_aggregateValuesObjectAndDataEmpty_fail() throws JSONException {
1309         Trigger trigger =
1310                 TriggerFixture.getValidTriggerBuilder()
1311                         .setId("triggerId1")
1312                         .setAggregateValuesString("{}")
1313                         .setAggregateTriggerData("[]")
1314                         .build();
1315         assertThat(trigger.hasAggregatableData(mFlags)).isFalse();
1316     }
1317 
1318     @Test
hasAggregatableData_aggregateValuesArrayAndDataEmpty_fail()1319     public void hasAggregatableData_aggregateValuesArrayAndDataEmpty_fail() throws JSONException {
1320         when(mFlags.getMeasurementEnableAggregateValueFilters()).thenReturn(true);
1321         Trigger trigger =
1322                 TriggerFixture.getValidTriggerBuilder()
1323                         .setId("triggerId1")
1324                         .setAggregateValuesString("[]")
1325                         .setAggregateTriggerData("[]")
1326                         .build();
1327         assertThat(trigger.hasAggregatableData(mFlags)).isFalse();
1328     }
1329 
assertInvalidTriggerArguments( Uri attributionDestination, String enrollmentId, Uri registrant, Long triggerTime, String eventTriggers, String aggregateTriggerData, String aggregateValues, String filters, String notFilters, UnsignedLong debugKey, String mAttributionConfig, String mAdtechBitMapping, Uri registrationOrigin, Trigger.SourceRegistrationTimeConfig sourceRegistrationTimeConfig)1330     private void assertInvalidTriggerArguments(
1331             Uri attributionDestination,
1332             String enrollmentId,
1333             Uri registrant,
1334             Long triggerTime,
1335             String eventTriggers,
1336             String aggregateTriggerData,
1337             String aggregateValues,
1338             String filters,
1339             String notFilters,
1340             UnsignedLong debugKey,
1341             String mAttributionConfig,
1342             String mAdtechBitMapping,
1343             Uri registrationOrigin,
1344             Trigger.SourceRegistrationTimeConfig sourceRegistrationTimeConfig) {
1345         assertThrows(
1346                 IllegalArgumentException.class,
1347                 () ->
1348                         new Trigger.Builder()
1349                                 .setAttributionDestination(attributionDestination)
1350                                 .setEnrollmentId(enrollmentId)
1351                                 .setRegistrant(registrant)
1352                                 .setTriggerTime(triggerTime)
1353                                 .setEventTriggers(eventTriggers)
1354                                 .setAggregateTriggerData(aggregateTriggerData)
1355                                 .setAggregateValuesString(aggregateValues)
1356                                 .setFilters(filters)
1357                                 .setNotFilters(notFilters)
1358                                 .setDebugKey(debugKey)
1359                                 .setAttributionConfig(mAttributionConfig)
1360                                 .setAdtechBitMapping(mAdtechBitMapping)
1361                                 .setRegistrationOrigin(registrationOrigin)
1362                                 .setAggregatableSourceRegistrationTimeConfig(
1363                                         sourceRegistrationTimeConfig)
1364                                 .build());
1365     }
1366 
createFilterJSONArray()1367     private JSONArray createFilterJSONArray() throws JSONException {
1368         JSONObject filterMap = new JSONObject();
1369         filterMap.put(
1370                 "conversion_subdomain", new JSONArray(Arrays.asList("electronics.megastore")));
1371         filterMap.put("product", new JSONArray(Arrays.asList("1234", "2345")));
1372         JSONArray filterSet = new JSONArray();
1373         filterSet.put(filterMap);
1374         return filterSet;
1375     }
1376 
createXNetworkDataJSONObject()1377     private JSONObject createXNetworkDataJSONObject() throws JSONException {
1378         JSONObject xNetworkData = new JSONObject();
1379         xNetworkData.put("key_offset", 10L);
1380         return xNetworkData;
1381     }
1382 
createAttributionConfigJSONArray()1383     private JSONArray createAttributionConfigJSONArray() throws JSONException {
1384         JSONArray attributionConfigList = new JSONArray();
1385         List<String> adtechIds = new ArrayList<>(Arrays.asList("AdTech1-Ads", "AdTech2-Ads"));
1386         for (String adtechId : adtechIds) {
1387             JSONObject attributionConfig = new JSONObject();
1388             attributionConfig.put("source_network", adtechId);
1389             JSONObject sourcePriorityRange = new JSONObject();
1390             sourcePriorityRange.put("start", 100L);
1391             sourcePriorityRange.put("end", 1000L);
1392             attributionConfig.put("source_priority_range", sourcePriorityRange);
1393             JSONObject sourceFilters = new JSONObject();
1394             sourceFilters.put("campaign_type", new JSONArray(Arrays.asList("install")));
1395             sourceFilters.put("source_type", new JSONArray(Arrays.asList("navigation")));
1396             JSONArray sourceFilterSet = new JSONArray();
1397             sourceFilterSet.put(sourceFilters);
1398             attributionConfig.put("source_filters", sourceFilterSet);
1399             JSONObject sourceNotFilters = new JSONObject();
1400             sourceNotFilters.put("campaign_type", new JSONArray(Arrays.asList("product")));
1401             JSONArray sourceNotFilterSet = new JSONArray();
1402             sourceNotFilterSet.put(sourceNotFilters);
1403             attributionConfig.put("source_not_filters", sourceNotFilterSet);
1404             attributionConfig.put("source_expiry_override", 600000L);
1405             attributionConfig.put("priority", 99L);
1406             attributionConfig.put("expiry", 604800L);
1407             JSONObject filterData = new JSONObject();
1408             filterData.put("campaign_type", new JSONArray(Arrays.asList("install")));
1409             JSONArray filterDataSet = new JSONArray();
1410             filterDataSet.put(filterData);
1411             attributionConfig.put("filter_data", filterDataSet);
1412             attributionConfig.put("post_install_exclusivity_window", 100000L);
1413             attributionConfigList.put(attributionConfig);
1414         }
1415         return attributionConfigList;
1416     }
1417 }
1418