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