• 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 android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.net.Uri;
23 
24 import com.android.adservices.service.measurement.aggregation.AggregatableAttributionTrigger;
25 import com.android.adservices.service.measurement.aggregation.AggregateDeduplicationKey;
26 import com.android.adservices.service.measurement.aggregation.AggregateTriggerData;
27 import com.android.adservices.service.measurement.util.Filter;
28 import com.android.adservices.service.measurement.util.UnsignedLong;
29 import com.android.adservices.service.measurement.util.Validation;
30 import com.android.adservices.service.measurement.util.Web;
31 
32 import org.json.JSONArray;
33 import org.json.JSONException;
34 import org.json.JSONObject;
35 
36 import java.lang.annotation.Retention;
37 import java.lang.annotation.RetentionPolicy;
38 import java.math.BigInteger;
39 import java.util.ArrayList;
40 import java.util.HashMap;
41 import java.util.HashSet;
42 import java.util.List;
43 import java.util.Map;
44 import java.util.Objects;
45 import java.util.Optional;
46 import java.util.Set;
47 
48 /** POJO for Trigger. */
49 public class Trigger {
50 
51     private String mId;
52     private Uri mAttributionDestination;
53     @EventSurfaceType private int mDestinationType;
54     private String mEnrollmentId;
55     private long mTriggerTime;
56     private @NonNull String mEventTriggers;
57     @Status private int mStatus;
58     private Uri mRegistrant;
59     private String mAggregateTriggerData;
60     private String mAggregateValues;
61     private String mAggregateDeduplicationKeys;
62     private boolean mIsDebugReporting;
63     private Optional<AggregatableAttributionTrigger> mAggregatableAttributionTrigger;
64     private String mFilters;
65     private String mNotFilters;
66     @Nullable private UnsignedLong mDebugKey;
67     private boolean mAdIdPermission;
68     private boolean mArDebugPermission;
69     @Nullable private String mAttributionConfig;
70     @Nullable private String mAdtechKeyMapping;
71     @Nullable private String mDebugJoinKey;
72     @Nullable private String mPlatformAdId;
73     @Nullable private String mDebugAdId;
74     private Uri mRegistrationOrigin;
75 
76     @IntDef(value = {Status.PENDING, Status.IGNORED, Status.ATTRIBUTED, Status.MARKED_TO_DELETE})
77     @Retention(RetentionPolicy.SOURCE)
78     public @interface Status {
79         int PENDING = 0;
80         int IGNORED = 1;
81         int ATTRIBUTED = 2;
82         int MARKED_TO_DELETE = 3;
83     }
84 
Trigger()85     private Trigger() {
86         mStatus = Status.PENDING;
87         // Making this default explicit since it anyway occur on an uninitialised int field.
88         mDestinationType = EventSurfaceType.APP;
89         mIsDebugReporting = false;
90     }
91 
92     @Override
equals(Object obj)93     public boolean equals(Object obj) {
94         if (!(obj instanceof Trigger)) {
95             return false;
96         }
97         Trigger trigger = (Trigger) obj;
98         return Objects.equals(mId, trigger.getId())
99                 && Objects.equals(mAttributionDestination, trigger.mAttributionDestination)
100                 && mDestinationType == trigger.mDestinationType
101                 && Objects.equals(mEnrollmentId, trigger.mEnrollmentId)
102                 && mTriggerTime == trigger.mTriggerTime
103                 && Objects.equals(mDebugKey, trigger.mDebugKey)
104                 && Objects.equals(mEventTriggers, trigger.mEventTriggers)
105                 && mStatus == trigger.mStatus
106                 && mIsDebugReporting == trigger.mIsDebugReporting
107                 && mAdIdPermission == trigger.mAdIdPermission
108                 && mArDebugPermission == trigger.mArDebugPermission
109                 && Objects.equals(mRegistrant, trigger.mRegistrant)
110                 && Objects.equals(mAggregateTriggerData, trigger.mAggregateTriggerData)
111                 && Objects.equals(mAggregateValues, trigger.mAggregateValues)
112                 && Objects.equals(
113                         mAggregatableAttributionTrigger, trigger.mAggregatableAttributionTrigger)
114                 && Objects.equals(mFilters, trigger.mFilters)
115                 && Objects.equals(mNotFilters, trigger.mNotFilters)
116                 && Objects.equals(mAttributionConfig, trigger.mAttributionConfig)
117                 && Objects.equals(mAdtechKeyMapping, trigger.mAdtechKeyMapping)
118                 && Objects.equals(mAggregateDeduplicationKeys, trigger.mAggregateDeduplicationKeys)
119                 && Objects.equals(mDebugJoinKey, trigger.mDebugJoinKey)
120                 && Objects.equals(mPlatformAdId, trigger.mPlatformAdId)
121                 && Objects.equals(mDebugAdId, trigger.mDebugAdId)
122                 && Objects.equals(mRegistrationOrigin, trigger.mRegistrationOrigin);
123     }
124 
125     @Override
hashCode()126     public int hashCode() {
127         return Objects.hash(
128                 mId,
129                 mAttributionDestination,
130                 mDestinationType,
131                 mEnrollmentId,
132                 mTriggerTime,
133                 mEventTriggers,
134                 mStatus,
135                 mAggregateTriggerData,
136                 mAggregateValues,
137                 mAggregatableAttributionTrigger,
138                 mFilters,
139                 mNotFilters,
140                 mDebugKey,
141                 mAdIdPermission,
142                 mArDebugPermission,
143                 mAttributionConfig,
144                 mAdtechKeyMapping,
145                 mAggregateDeduplicationKeys,
146                 mDebugJoinKey,
147                 mPlatformAdId,
148                 mDebugAdId,
149                 mRegistrationOrigin);
150     }
151 
152     /** Unique identifier for the {@link Trigger}. */
getId()153     public String getId() {
154         return mId;
155     }
156 
157     /**
158      * Destination where {@link Trigger} occurred.
159      */
getAttributionDestination()160     public Uri getAttributionDestination() {
161         return mAttributionDestination;
162     }
163 
164     /** Destination type of the {@link Trigger}. */
165     @EventSurfaceType
getDestinationType()166     public int getDestinationType() {
167         return mDestinationType;
168     }
169 
170     /**
171      * AdTech enrollment ID.
172      */
getEnrollmentId()173     public String getEnrollmentId() {
174         return mEnrollmentId;
175     }
176 
177     /**
178      * Time when the event occurred.
179      */
getTriggerTime()180     public long getTriggerTime() {
181         return mTriggerTime;
182     }
183 
184     /**
185      * Event triggers containing priority, de-dup key, trigger data and event-level filters info.
186      */
getEventTriggers()187     public String getEventTriggers() {
188         return mEventTriggers;
189     }
190 
191     /** Current state of the {@link Trigger}. */
192     @Status
getStatus()193     public int getStatus() {
194         return mStatus;
195     }
196 
197     /**
198      * Set the status.
199      */
setStatus(@tatus int status)200     public void setStatus(@Status int status) {
201         mStatus = status;
202     }
203 
204     /**
205      * Registrant of this trigger, primarily an App.
206      */
getRegistrant()207     public Uri getRegistrant() {
208         return mRegistrant;
209     }
210 
211     /**
212      * Returns aggregate trigger data string used for aggregation. aggregate trigger data json is a
213      * JSONArray. example: [ // Each dict independently adds pieces to multiple source keys. { //
214      * Conversion type purchase = 2 at a 9 bit key_offset, i.e. 2 << 9. // A 9 bit key_offset is
215      * needed because there are 511 possible campaigns, which // will take up 9 bits in the
216      * resulting key. "key_piece": "0x400", // Apply this key piece to: "source_keys":
217      * ["campaignCounts"] }, { // Purchase category shirts = 21 at a 7 bit key_offset, i.e. 21 << 7.
218      * // A 7 bit key_offset is needed because there are ~100 regions for the geo key, // which will
219      * take up 7 bits of space in the resulting key. "key_piece": "0xA80", // Apply this key piece
220      * to: "source_keys": ["geoValue", "nonMatchingKeyIdsAreIgnored"] } ]
221      */
getAggregateTriggerData()222     public String getAggregateTriggerData() {
223         return mAggregateTriggerData;
224     }
225 
226     /**
227      * Returns aggregate value string used for aggregation. aggregate value json is a JSONObject.
228      * example:
229      * {
230      *   "campaignCounts": 32768,
231      *   "geoValue": 1664
232      * }
233      */
getAggregateValues()234     public String getAggregateValues() {
235         return mAggregateValues;
236     }
237 
238     /**
239      * Returns a list of aggregate deduplication keys. aggregate deduplication key is a JSONObject.
240      * example: { "deduplication_key": "32768", "filters": [ {type: [filter_1, filter_2]} ],
241      * "not_filters": [ {type: [not_filter_1, not_filter_2]} ] }
242      */
getAggregateDeduplicationKeys()243     public String getAggregateDeduplicationKeys() {
244         return mAggregateDeduplicationKeys;
245     }
246 
247     /**
248      * Returns the AggregatableAttributionTrigger object, which is constructed using the aggregate
249      * trigger data string and aggregate values string in Trigger.
250      */
getAggregatableAttributionTrigger()251     public Optional<AggregatableAttributionTrigger> getAggregatableAttributionTrigger()
252             throws JSONException {
253         if (mAggregatableAttributionTrigger != null) {
254             return mAggregatableAttributionTrigger;
255         }
256 
257         mAggregatableAttributionTrigger = parseAggregateTrigger();
258         return mAggregatableAttributionTrigger;
259     }
260 
261     /**
262      * Returns top level filters. The value is in json format.
263      *
264      * <p>Will be used for deciding if the trigger can be attributed to the source. If the source
265      * fails the filtering against these filters then no reports(event/aggregate) are generated.
266      * example: { "key1" : ["value11", "value12"], "key2" : ["value21", "value22"] }
267      */
getFilters()268     public String getFilters() {
269         return mFilters;
270     }
271 
272     /** Is Ad Tech Opt-in to Debug Reporting {@link Trigger}. */
isDebugReporting()273     public boolean isDebugReporting() {
274         return mIsDebugReporting;
275     }
276 
277     /** Is Ad ID Permission Enabled. */
hasAdIdPermission()278     public boolean hasAdIdPermission() {
279         return mAdIdPermission;
280     }
281 
282     /** Is Ar Debug Permission Enabled. */
hasArDebugPermission()283     public boolean hasArDebugPermission() {
284         return mArDebugPermission;
285     }
286 
287     /**
288      * Returns top level not-filters. The value is in json format.
289      */
getNotFilters()290     public String getNotFilters() {
291         return mNotFilters;
292     }
293 
294     /** Debug key of {@link Trigger}. */
295     @Nullable
getDebugKey()296     public UnsignedLong getDebugKey() {
297         return mDebugKey;
298     }
299 
300     /**
301      * Returns field attribution config JSONArray as String. example: [{ "source_network":
302      * "AdTech1-Ads", "source_priority_range": { “start”: 100, “end”: 1000 }, "source_filters": {
303      * "campaign_type": ["install"], "source_type": ["navigation"], }, "priority": "99", "expiry":
304      * "604800", "filter_data":{ "campaign_type": ["install"], } }]
305      */
306     @Nullable
getAttributionConfig()307     public String getAttributionConfig() {
308         return mAttributionConfig;
309     }
310 
311     /**
312      * Returns adtech bit mapping JSONObject as String. example: "x_network_key_mapping": {
313      * "AdTechA-enrollment_id": "0x1", "AdTechB-enrollment_id": "0x2", }
314      */
315     @Nullable
getAdtechKeyMapping()316     public String getAdtechKeyMapping() {
317         return mAdtechKeyMapping;
318     }
319 
320     /**
321      * Returns join key that should be matched with source's join key at the time of generating
322      * reports.
323      */
324     @Nullable
getDebugJoinKey()325     public String getDebugJoinKey() {
326         return mDebugJoinKey;
327     }
328 
329     /**
330      * Returns SHA256 hash of AdID from getAdId() on app registration concatenated with enrollment
331      * ID, to be matched with a web source's {@link Source#getDebugAdId()} value at the time of
332      * generating reports.
333      */
334     @Nullable
getPlatformAdId()335     public String getPlatformAdId() {
336         return mPlatformAdId;
337     }
338 
339     /**
340      * Returns SHA256 hash of AdID from registration response on web registration concatenated with
341      * enrollment ID, to be matched with an app source's {@link Source#getPlatformAdId()} value at
342      * the time of generating reports.
343      */
344     @Nullable
getDebugAdId()345     public String getDebugAdId() {
346         return mDebugAdId;
347     }
348 
349     /** Returns registration origin used to register the source */
getRegistrationOrigin()350     public Uri getRegistrationOrigin() {
351         return mRegistrationOrigin;
352     }
353 
354     /**
355      * Generates AggregatableAttributionTrigger from aggregate trigger data string and aggregate
356      * values string in Trigger.
357      */
parseAggregateTrigger()358     private Optional<AggregatableAttributionTrigger> parseAggregateTrigger()
359             throws JSONException, NumberFormatException {
360         if (this.mAggregateValues == null) {
361             return Optional.empty();
362         }
363         JSONArray triggerDataArray = this.mAggregateTriggerData == null
364                 ? new JSONArray()
365                 : new JSONArray(this.mAggregateTriggerData);
366         List<AggregateTriggerData> triggerDataList = new ArrayList<>();
367         for (int i = 0; i < triggerDataArray.length(); i++) {
368             JSONObject triggerDatum = triggerDataArray.getJSONObject(i);
369             // Remove "0x" prefix.
370             String hexString = triggerDatum.getString("key_piece").substring(2);
371             BigInteger bigInteger = new BigInteger(hexString, 16);
372             JSONArray sourceKeys = triggerDatum.getJSONArray("source_keys");
373             Set<String> sourceKeySet = new HashSet<>();
374             for (int j = 0; j < sourceKeys.length(); j++) {
375                 sourceKeySet.add(sourceKeys.getString(j));
376             }
377             AggregateTriggerData.Builder builder =
378                     new AggregateTriggerData.Builder()
379                             .setKey(bigInteger)
380                             .setSourceKeys(sourceKeySet);
381             if (triggerDatum.has("filters") && !triggerDatum.isNull("filters")) {
382                 List<FilterMap> filterSet =
383                         Filter.deserializeFilterSet(triggerDatum.getJSONArray("filters"));
384                 builder.setFilterSet(filterSet);
385             }
386             if (triggerDatum.has("not_filters")
387                     && !triggerDatum.isNull("not_filters")) {
388                 List<FilterMap> notFilterSet =
389                         Filter.deserializeFilterSet(triggerDatum.getJSONArray("not_filters"));
390                 builder.setNotFilterSet(notFilterSet);
391             }
392             if (!triggerDatum.isNull("x_network_data")) {
393                 JSONObject xNetworkDataJson = triggerDatum.getJSONObject("x_network_data");
394                 XNetworkData xNetworkData = new XNetworkData.Builder(xNetworkDataJson).build();
395                 builder.setXNetworkData(xNetworkData);
396             }
397             triggerDataList.add(builder.build());
398         }
399         JSONObject values = new JSONObject(this.mAggregateValues);
400         Map<String, Integer> valueMap = new HashMap<>();
401         for (String key : values.keySet()) {
402             valueMap.put(key, values.getInt(key));
403         }
404         List<AggregateDeduplicationKey> dedupKeyList = new ArrayList<>();
405         if (getAggregateDeduplicationKeys() != null) {
406             JSONArray dedupKeyObjects = new JSONArray(this.getAggregateDeduplicationKeys());
407             for (int i = 0; i < dedupKeyObjects.length(); i++) {
408                 JSONObject dedupKeyObject = dedupKeyObjects.getJSONObject(i);
409                 AggregateDeduplicationKey.Builder builder = new AggregateDeduplicationKey.Builder();
410                 if (dedupKeyObject.has("deduplication_key")
411                         && !dedupKeyObject.isNull("deduplication_key")) {
412                     builder.setDeduplicationKey(
413                             new UnsignedLong(dedupKeyObject.getString("deduplication_key")));
414                 }
415                 if (dedupKeyObject.has("filters") && !dedupKeyObject.isNull("filters")) {
416                     List<FilterMap> filterSet =
417                             Filter.deserializeFilterSet(dedupKeyObject.getJSONArray("filters"));
418                     builder.setFilterSet(filterSet);
419                 }
420                 if (dedupKeyObject.has("not_filters") && !dedupKeyObject.isNull("not_filters")) {
421                     List<FilterMap> notFilterSet =
422                             Filter.deserializeFilterSet(dedupKeyObject.getJSONArray("not_filters"));
423                     builder.setNotFilterSet(notFilterSet);
424                 }
425                 dedupKeyList.add(builder.build());
426             }
427         }
428         return Optional.of(
429                 new AggregatableAttributionTrigger.Builder()
430                         .setTriggerData(triggerDataList)
431                         .setValues(valueMap)
432                         .setAggregateDeduplicationKeys(dedupKeyList)
433                         .build());
434     }
435 
436     /**
437      * Parses the json array under {@link #mEventTriggers} to form a list of {@link EventTrigger}s.
438      *
439      * @return list of {@link EventTrigger}s
440      * @throws JSONException if JSON parsing fails
441      */
parseEventTriggers()442     public List<EventTrigger> parseEventTriggers() throws JSONException {
443         JSONArray jsonArray = new JSONArray(this.mEventTriggers);
444         List<EventTrigger> eventTriggers = new ArrayList<>();
445 
446         for (int i = 0; i < jsonArray.length(); i++) {
447             JSONObject eventTrigger = jsonArray.getJSONObject(i);
448 
449             EventTrigger.Builder eventTriggerBuilder =
450                     new EventTrigger.Builder(
451                             new UnsignedLong(
452                                     eventTrigger.getString(
453                                             EventTriggerContract.TRIGGER_DATA)));
454 
455             if (!eventTrigger.isNull(EventTriggerContract.PRIORITY)) {
456                 eventTriggerBuilder.setTriggerPriority(
457                         eventTrigger.getLong(EventTriggerContract.PRIORITY));
458             }
459 
460             if (!eventTrigger.isNull(EventTriggerContract.DEDUPLICATION_KEY)) {
461                 eventTriggerBuilder.setDedupKey(new UnsignedLong(
462                         eventTrigger.getString(EventTriggerContract.DEDUPLICATION_KEY)));
463             }
464 
465             if (!eventTrigger.isNull(EventTriggerContract.FILTERS)) {
466                 List<FilterMap> filterSet =
467                         Filter.deserializeFilterSet(
468                                 eventTrigger.getJSONArray(EventTriggerContract.FILTERS));
469                 eventTriggerBuilder.setFilterSet(filterSet);
470             }
471 
472             if (!eventTrigger.isNull(EventTriggerContract.NOT_FILTERS)) {
473                 List<FilterMap> notFilterSet =
474                         Filter.deserializeFilterSet(
475                                 eventTrigger.getJSONArray(EventTriggerContract.NOT_FILTERS));
476                 eventTriggerBuilder.setNotFilterSet(notFilterSet);
477             }
478             eventTriggers.add(eventTriggerBuilder.build());
479         }
480 
481         return eventTriggers;
482     }
483 
484     /**
485      * Parses the json object under {@link #mAdtechKeyMapping} to create a mapping of adtechs to
486      * their bits.
487      *
488      * @return mapping of String to BigInteger
489      * @throws JSONException if JSON parsing fails
490      * @throws NumberFormatException if BigInteger parsing fails
491      */
492     @Nullable
parseAdtechKeyMapping()493     public Map<String, BigInteger> parseAdtechKeyMapping()
494             throws JSONException, NumberFormatException {
495         if (mAdtechKeyMapping == null) {
496             return null;
497         }
498         Map<String, BigInteger> adtechBitMapping = new HashMap<>();
499         JSONObject jsonObject = new JSONObject(mAdtechKeyMapping);
500         for (String key : jsonObject.keySet()) {
501             // Remove "0x" prefix.
502             String hexString = jsonObject.getString(key).substring(2);
503             BigInteger bigInteger = new BigInteger(hexString, 16);
504             adtechBitMapping.put(key, bigInteger);
505         }
506         return adtechBitMapping;
507     }
508 
509     /**
510      * Returns a {@code Uri} with scheme and (1) public suffix + 1 in case of a web destination, or
511      * (2) the Android package name in case of an app destination. Returns null if extracting the
512      * public suffix + 1 fails.
513      */
514     @Nullable
getAttributionDestinationBaseUri()515     public Uri getAttributionDestinationBaseUri() {
516         if (mDestinationType == EventSurfaceType.APP) {
517             return mAttributionDestination;
518         } else {
519             Optional<Uri> uri = Web.topPrivateDomainAndScheme(mAttributionDestination);
520             return uri.orElse(null);
521         }
522     }
523 
524     /** Builder for {@link Trigger}. */
525     public static final class Builder {
526 
527         private final Trigger mBuilding;
528 
Builder()529         public Builder() {
530             mBuilding = new Trigger();
531         }
532 
533         /** See {@link Trigger#getId()}. */
534         @NonNull
setId(String id)535         public Builder setId(String id) {
536             mBuilding.mId = id;
537             return this;
538         }
539 
540         /** See {@link Trigger#getAttributionDestination()}. */
541         @NonNull
setAttributionDestination(Uri attributionDestination)542         public Builder setAttributionDestination(Uri attributionDestination) {
543             Validation.validateUri(attributionDestination);
544             mBuilding.mAttributionDestination = attributionDestination;
545             return this;
546         }
547 
548         /** See {@link Trigger#getDestinationType()}. */
549         @NonNull
setDestinationType(@ventSurfaceType int destinationType)550         public Builder setDestinationType(@EventSurfaceType int destinationType) {
551             mBuilding.mDestinationType = destinationType;
552             return this;
553         }
554 
555         /** See {@link Trigger#getEnrollmentId()}. */
556         @NonNull
setEnrollmentId(String enrollmentId)557         public Builder setEnrollmentId(String enrollmentId) {
558             mBuilding.mEnrollmentId = enrollmentId;
559             return this;
560         }
561 
562         /** See {@link Trigger#getStatus()}. */
563         @NonNull
setStatus(@tatus int status)564         public Builder setStatus(@Status int status) {
565             mBuilding.mStatus = status;
566             return this;
567         }
568 
569         /** See {@link Trigger#getTriggerTime()}. */
570         @NonNull
setTriggerTime(long triggerTime)571         public Builder setTriggerTime(long triggerTime) {
572             mBuilding.mTriggerTime = triggerTime;
573             return this;
574         }
575 
576         /** See {@link Trigger#getEventTriggers()}. */
577         @NonNull
setEventTriggers(@onNull String eventTriggers)578         public Builder setEventTriggers(@NonNull String eventTriggers) {
579             Validation.validateNonNull(eventTriggers);
580             mBuilding.mEventTriggers = eventTriggers;
581             return this;
582         }
583 
584         /** See {@link Trigger#getRegistrant()} */
585         @NonNull
setRegistrant(@onNull Uri registrant)586         public Builder setRegistrant(@NonNull Uri registrant) {
587             Validation.validateUri(registrant);
588             mBuilding.mRegistrant = registrant;
589             return this;
590         }
591 
592         /** See {@link Trigger#getAggregateTriggerData()}. */
593         @NonNull
setAggregateTriggerData(@ullable String aggregateTriggerData)594         public Builder setAggregateTriggerData(@Nullable String aggregateTriggerData) {
595             mBuilding.mAggregateTriggerData = aggregateTriggerData;
596             return this;
597         }
598 
599         /** See {@link Trigger#getAggregateValues()} */
600         @NonNull
setAggregateValues(@ullable String aggregateValues)601         public Builder setAggregateValues(@Nullable String aggregateValues) {
602             mBuilding.mAggregateValues = aggregateValues;
603             return this;
604         }
605 
606         /** See {@link Trigger#getAggregateDeduplicationKeys()} */
607         @NonNull
setAggregateDeduplicationKeys(@onNull String aggregateDeduplicationKeys)608         public Builder setAggregateDeduplicationKeys(@NonNull String aggregateDeduplicationKeys) {
609             mBuilding.mAggregateDeduplicationKeys = aggregateDeduplicationKeys;
610             return this;
611         }
612 
613         /** See {@link Trigger#getFilters()} */
614         @NonNull
setFilters(@ullable String filters)615         public Builder setFilters(@Nullable String filters) {
616             mBuilding.mFilters = filters;
617             return this;
618         }
619 
620         /** See {@link Trigger#isDebugReporting()} */
setIsDebugReporting(boolean isDebugReporting)621         public Trigger.Builder setIsDebugReporting(boolean isDebugReporting) {
622             mBuilding.mIsDebugReporting = isDebugReporting;
623             return this;
624         }
625 
626         /** See {@link Trigger#hasAdIdPermission()} */
setAdIdPermission(boolean adIdPermission)627         public Trigger.Builder setAdIdPermission(boolean adIdPermission) {
628             mBuilding.mAdIdPermission = adIdPermission;
629             return this;
630         }
631 
632         /** See {@link Trigger#hasArDebugPermission()} */
setArDebugPermission(boolean arDebugPermission)633         public Trigger.Builder setArDebugPermission(boolean arDebugPermission) {
634             mBuilding.mArDebugPermission = arDebugPermission;
635             return this;
636         }
637 
638         /** See {@link Trigger#getNotFilters()} */
639         @NonNull
setNotFilters(@ullable String notFilters)640         public Builder setNotFilters(@Nullable String notFilters) {
641             mBuilding.mNotFilters = notFilters;
642             return this;
643         }
644 
645         /** See {@link Trigger#getDebugKey()} */
setDebugKey(@ullable UnsignedLong debugKey)646         public Builder setDebugKey(@Nullable UnsignedLong debugKey) {
647             mBuilding.mDebugKey = debugKey;
648             return this;
649         }
650 
651         /** See {@link Trigger#getAttributionConfig()} ()} */
setAttributionConfig(@ullable String attributionConfig)652         public Builder setAttributionConfig(@Nullable String attributionConfig) {
653             mBuilding.mAttributionConfig = attributionConfig;
654             return this;
655         }
656 
657         /** See {@link Trigger#getAdtechKeyMapping()} ()} */
setAdtechBitMapping(@ullable String adtechBitMapping)658         public Builder setAdtechBitMapping(@Nullable String adtechBitMapping) {
659             mBuilding.mAdtechKeyMapping = adtechBitMapping;
660             return this;
661         }
662 
663         /** See {@link Trigger#getAggregatableAttributionTrigger()} */
664         @NonNull
setAggregatableAttributionTrigger( @ullable AggregatableAttributionTrigger aggregatableAttributionTrigger)665         public Builder setAggregatableAttributionTrigger(
666                 @Nullable AggregatableAttributionTrigger aggregatableAttributionTrigger) {
667             mBuilding.mAggregatableAttributionTrigger =
668                     Optional.ofNullable(aggregatableAttributionTrigger);
669             return this;
670         }
671 
672         /** See {@link Trigger#getDebugJoinKey()} */
673         @NonNull
setDebugJoinKey(@ullable String debugJoinKey)674         public Builder setDebugJoinKey(@Nullable String debugJoinKey) {
675             mBuilding.mDebugJoinKey = debugJoinKey;
676             return this;
677         }
678 
679         /** See {@link Trigger#getPlatformAdId()} */
680         @NonNull
setPlatformAdId(@ullable String platformAdId)681         public Builder setPlatformAdId(@Nullable String platformAdId) {
682             mBuilding.mPlatformAdId = platformAdId;
683             return this;
684         }
685 
686         /** See {@link Trigger#getDebugAdId()} */
687         @NonNull
setDebugAdId(@ullable String debugAdId)688         public Builder setDebugAdId(@Nullable String debugAdId) {
689             mBuilding.mDebugAdId = debugAdId;
690             return this;
691         }
692 
693         /** See {@link Source#getRegistrationOrigin()} ()} */
694         @NonNull
setRegistrationOrigin(Uri registrationOrigin)695         public Trigger.Builder setRegistrationOrigin(Uri registrationOrigin) {
696             mBuilding.mRegistrationOrigin = registrationOrigin;
697             return this;
698         }
699 
700         /** Build the {@link Trigger}. */
701         @NonNull
build()702         public Trigger build() {
703             Validation.validateNonNull(
704                     mBuilding.mAttributionDestination,
705                     mBuilding.mEnrollmentId,
706                     mBuilding.mRegistrant,
707                     mBuilding.mRegistrationOrigin);
708 
709             return mBuilding;
710         }
711     }
712 
713     /** Event trigger field keys. */
714     public interface EventTriggerContract {
715         String TRIGGER_DATA = "trigger_data";
716         String PRIORITY = "priority";
717         String DEDUPLICATION_KEY = "deduplication_key";
718         String FILTERS = "filters";
719         String NOT_FILTERS = "not_filters";
720     }
721 }
722