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.AggregatableAttributionSource; 25 import com.android.adservices.service.measurement.util.UnsignedLong; 26 import com.android.adservices.service.measurement.util.Validation; 27 28 import com.google.common.collect.ImmutableMultiset; 29 30 import org.json.JSONException; 31 import org.json.JSONObject; 32 33 import java.lang.annotation.Retention; 34 import java.lang.annotation.RetentionPolicy; 35 import java.math.BigInteger; 36 import java.util.ArrayList; 37 import java.util.Collections; 38 import java.util.List; 39 import java.util.Objects; 40 import java.util.Optional; 41 import java.util.TreeMap; 42 43 /** 44 * POJO for Source. 45 */ 46 public class Source { 47 private String mId; 48 private UnsignedLong mEventId; 49 private Uri mPublisher; 50 @EventSurfaceType private int mPublisherType; 51 private List<Uri> mAppDestinations; 52 private List<Uri> mWebDestinations; 53 private String mEnrollmentId; 54 private Uri mRegistrant; 55 private SourceType mSourceType; 56 private long mPriority; 57 @Status private int mStatus; 58 private long mEventTime; 59 private long mExpiryTime; 60 private long mEventReportWindow; 61 private long mAggregatableReportWindow; 62 private List<UnsignedLong> mAggregateReportDedupKeys; 63 private List<UnsignedLong> mEventReportDedupKeys; 64 @AttributionMode private int mAttributionMode; 65 private long mInstallAttributionWindow; 66 private long mInstallCooldownWindow; 67 @Nullable private UnsignedLong mDebugKey; 68 private boolean mIsInstallAttributed; 69 private boolean mIsDebugReporting; 70 private String mFilterDataString; 71 private FilterMap mFilterData; 72 private String mAggregateSource; 73 private int mAggregateContributions; 74 private Optional<AggregatableAttributionSource> mAggregatableAttributionSource; 75 private boolean mAdIdPermission; 76 private boolean mArDebugPermission; 77 @Nullable private String mRegistrationId; 78 @Nullable private String mSharedAggregationKeys; 79 @Nullable private Long mInstallTime; 80 @Nullable private String mParentId; 81 @Nullable private String mDebugJoinKey; 82 @Nullable private String mPlatformAdId; 83 @Nullable private String mDebugAdId; 84 private Uri mRegistrationOrigin; 85 @Nullable private ReportSpec mFlexEventReportSpec; 86 private boolean mCoarseEventReportDestinations; 87 88 @IntDef(value = {Status.ACTIVE, Status.IGNORED, Status.MARKED_TO_DELETE}) 89 @Retention(RetentionPolicy.SOURCE) 90 public @interface Status { 91 int ACTIVE = 0; 92 int IGNORED = 1; 93 int MARKED_TO_DELETE = 2; 94 } 95 96 @IntDef(value = { 97 AttributionMode.UNASSIGNED, 98 AttributionMode.TRUTHFULLY, 99 AttributionMode.NEVER, 100 AttributionMode.FALSELY, 101 }) 102 @Retention(RetentionPolicy.SOURCE) 103 public @interface AttributionMode { 104 int UNASSIGNED = 0; 105 int TRUTHFULLY = 1; 106 int NEVER = 2; 107 int FALSELY = 3; 108 } 109 110 public enum SourceType { 111 EVENT("event"), 112 NAVIGATION("navigation"); 113 114 private final String mValue; 115 SourceType(String value)116 SourceType(String value) { 117 mValue = value; 118 } 119 getValue()120 public String getValue() { 121 return mValue; 122 } 123 } 124 Source()125 private Source() { 126 mEventReportDedupKeys = new ArrayList<>(); 127 mAggregateReportDedupKeys = new ArrayList<>(); 128 mStatus = Status.ACTIVE; 129 mSourceType = SourceType.EVENT; 130 // Making this default explicit since it anyway would occur on an uninitialised int field. 131 mPublisherType = EventSurfaceType.APP; 132 mAttributionMode = AttributionMode.UNASSIGNED; 133 mIsInstallAttributed = false; 134 mIsDebugReporting = false; 135 } 136 137 /** Class for storing fake report data. */ 138 public static class FakeReport { 139 private final UnsignedLong mTriggerData; 140 private final long mReportingTime; 141 private final List<Uri> mDestinations; 142 FakeReport(UnsignedLong triggerData, long reportingTime, List<Uri> destinations)143 public FakeReport(UnsignedLong triggerData, long reportingTime, List<Uri> destinations) { 144 mTriggerData = triggerData; 145 mReportingTime = reportingTime; 146 mDestinations = destinations; 147 } 148 149 @Override equals(Object o)150 public boolean equals(Object o) { 151 if (this == o) return true; 152 if (!(o instanceof FakeReport)) return false; 153 FakeReport that = (FakeReport) o; 154 return Objects.equals(mTriggerData, that.mTriggerData) 155 && mReportingTime == that.mReportingTime 156 && Objects.equals(mDestinations, that.mDestinations); 157 } 158 159 @Override hashCode()160 public int hashCode() { 161 return Objects.hash(mTriggerData, mReportingTime, mDestinations); 162 } 163 getReportingTime()164 public long getReportingTime() { 165 return mReportingTime; 166 } 167 getTriggerData()168 public UnsignedLong getTriggerData() { 169 return mTriggerData; 170 } 171 getDestinations()172 public List<Uri> getDestinations() { 173 return mDestinations; 174 } 175 } 176 177 /** 178 * Range of trigger metadata: [0, cardinality). 179 * @return Cardinality of {@link Trigger} metadata 180 */ getTriggerDataCardinality()181 public int getTriggerDataCardinality() { 182 return mSourceType == SourceType.EVENT 183 ? PrivacyParams.EVENT_TRIGGER_DATA_CARDINALITY 184 : PrivacyParams.getNavigationTriggerDataCardinality(); 185 } 186 187 @Override equals(Object obj)188 public boolean equals(Object obj) { 189 if (!(obj instanceof Source)) { 190 return false; 191 } 192 Source source = (Source) obj; 193 return Objects.equals(mPublisher, source.mPublisher) 194 && mPublisherType == source.mPublisherType 195 && areEqualNullableDestinations(mAppDestinations, source.mAppDestinations) 196 && areEqualNullableDestinations(mWebDestinations, source.mWebDestinations) 197 && Objects.equals(mEnrollmentId, source.mEnrollmentId) 198 && mPriority == source.mPriority 199 && mStatus == source.mStatus 200 && mExpiryTime == source.mExpiryTime 201 && mEventReportWindow == source.mEventReportWindow 202 && mAggregatableReportWindow == source.mAggregatableReportWindow 203 && mEventTime == source.mEventTime 204 && mAdIdPermission == source.mAdIdPermission 205 && mArDebugPermission == source.mArDebugPermission 206 && Objects.equals(mEventId, source.mEventId) 207 && Objects.equals(mDebugKey, source.mDebugKey) 208 && mSourceType == source.mSourceType 209 && Objects.equals(mEventReportDedupKeys, source.mEventReportDedupKeys) 210 && Objects.equals(mAggregateReportDedupKeys, source.mAggregateReportDedupKeys) 211 && Objects.equals(mRegistrant, source.mRegistrant) 212 && mAttributionMode == source.mAttributionMode 213 && mIsDebugReporting == source.mIsDebugReporting 214 && Objects.equals(mFilterDataString, source.mFilterDataString) 215 && Objects.equals(mAggregateSource, source.mAggregateSource) 216 && mAggregateContributions == source.mAggregateContributions 217 && Objects.equals( 218 mAggregatableAttributionSource, source.mAggregatableAttributionSource) 219 && Objects.equals(mRegistrationId, source.mRegistrationId) 220 && Objects.equals(mSharedAggregationKeys, source.mSharedAggregationKeys) 221 && Objects.equals(mParentId, source.mParentId) 222 && Objects.equals(mInstallTime, source.mInstallTime) 223 && Objects.equals(mDebugJoinKey, source.mDebugJoinKey) 224 && Objects.equals(mPlatformAdId, source.mPlatformAdId) 225 && Objects.equals(mDebugAdId, source.mDebugAdId) 226 && Objects.equals(mRegistrationOrigin, source.mRegistrationOrigin) 227 && Objects.equals(mFlexEventReportSpec, source.mFlexEventReportSpec) 228 && mCoarseEventReportDestinations == source.mCoarseEventReportDestinations; 229 } 230 231 @Override hashCode()232 public int hashCode() { 233 return Objects.hash( 234 mId, 235 mPublisher, 236 mPublisherType, 237 mAppDestinations, 238 mWebDestinations, 239 mEnrollmentId, 240 mPriority, 241 mStatus, 242 mExpiryTime, 243 mEventReportWindow, 244 mAggregatableReportWindow, 245 mEventTime, 246 mEventId, 247 mSourceType, 248 mEventReportDedupKeys, 249 mAggregateReportDedupKeys, 250 mFilterDataString, 251 mAggregateSource, 252 mAggregateContributions, 253 mAggregatableAttributionSource, 254 mDebugKey, 255 mAdIdPermission, 256 mArDebugPermission, 257 mRegistrationId, 258 mSharedAggregationKeys, 259 mInstallTime, 260 mDebugJoinKey, 261 mPlatformAdId, 262 mDebugAdId, 263 mRegistrationOrigin, 264 mDebugAdId, 265 mDebugJoinKey, 266 mFlexEventReportSpec, 267 mCoarseEventReportDestinations); 268 } 269 setAttributionMode(@ttributionMode int attributionMode)270 public void setAttributionMode(@AttributionMode int attributionMode) { 271 mAttributionMode = attributionMode; 272 } 273 274 /** 275 * Retrieve the attribution destinations corresponding to their destination type. 276 * 277 * @return a list of Uris. 278 */ getAttributionDestinations(@ventSurfaceType int destinationType)279 public List<Uri> getAttributionDestinations(@EventSurfaceType int destinationType) { 280 return destinationType == EventSurfaceType.APP ? mAppDestinations : mWebDestinations; 281 } 282 283 /** 284 * Unique identifier for the {@link Source}. 285 */ getId()286 public String getId() { 287 return mId; 288 } 289 290 /** 291 * Identifier provided by the registrant. 292 */ getEventId()293 public UnsignedLong getEventId() { 294 return mEventId; 295 } 296 297 /** 298 * Priority of the {@link Source}. 299 */ getPriority()300 public long getPriority() { 301 return mPriority; 302 } 303 304 /** 305 * Ad Tech enrollment ID 306 */ getEnrollmentId()307 public String getEnrollmentId() { 308 return mEnrollmentId; 309 } 310 311 /** Uri which registered the {@link Source}. */ getPublisher()312 public Uri getPublisher() { 313 return mPublisher; 314 } 315 316 /** The publisher type (e.g., app or web) {@link Source}. */ 317 @EventSurfaceType getPublisherType()318 public int getPublisherType() { 319 return mPublisherType; 320 } 321 322 /** Uris for the {@link Trigger}'s app destinations. */ 323 @Nullable getAppDestinations()324 public List<Uri> getAppDestinations() { 325 return mAppDestinations; 326 } 327 328 /** Uris for the {@link Trigger}'s web destinations. */ 329 @Nullable getWebDestinations()330 public List<Uri> getWebDestinations() { 331 return mWebDestinations; 332 } 333 334 /** 335 * Type of {@link Source}. Values: Event, Navigation. 336 */ getSourceType()337 public SourceType getSourceType() { 338 return mSourceType; 339 } 340 341 /** Time when {@link Source} will expire. */ getExpiryTime()342 public long getExpiryTime() { 343 return mExpiryTime; 344 } 345 346 /** Time when {@link Source} event report window will expire. */ getEventReportWindow()347 public long getEventReportWindow() { 348 return mEventReportWindow; 349 } 350 351 /** Time when {@link Source} aggregate report window will expire. */ getAggregatableReportWindow()352 public long getAggregatableReportWindow() { 353 return mAggregatableReportWindow; 354 } 355 356 /** Debug key of {@link Source}. */ 357 @Nullable getDebugKey()358 public UnsignedLong getDebugKey() { 359 return mDebugKey; 360 } 361 362 /** 363 * Time the event occurred. 364 */ getEventTime()365 public long getEventTime() { 366 return mEventTime; 367 } 368 369 /** Is Ad ID Permission Enabled. */ hasAdIdPermission()370 public boolean hasAdIdPermission() { 371 return mAdIdPermission; 372 } 373 374 /** Is Ar Debug Permission Enabled. */ hasArDebugPermission()375 public boolean hasArDebugPermission() { 376 return mArDebugPermission; 377 } 378 379 /** List of dedup keys for the attributed {@link Trigger}. */ getEventReportDedupKeys()380 public List<UnsignedLong> getEventReportDedupKeys() { 381 return mEventReportDedupKeys; 382 } 383 384 /** List of dedup keys used for generating Aggregate Reports. */ getAggregateReportDedupKeys()385 public List<UnsignedLong> getAggregateReportDedupKeys() { 386 return mAggregateReportDedupKeys; 387 } 388 389 /** Current status of the {@link Source}. */ 390 @Status getStatus()391 public int getStatus() { 392 return mStatus; 393 } 394 395 /** 396 * Registrant of this source, primarily an App. 397 */ getRegistrant()398 public Uri getRegistrant() { 399 return mRegistrant; 400 } 401 402 /** Selected mode for attribution. Values: Truthfully, Never, Falsely. */ 403 @AttributionMode getAttributionMode()404 public int getAttributionMode() { 405 return mAttributionMode; 406 } 407 408 /** 409 * Attribution window for install events. 410 */ getInstallAttributionWindow()411 public long getInstallAttributionWindow() { 412 return mInstallAttributionWindow; 413 } 414 415 /** 416 * Cooldown for attributing post-install {@link Trigger} events. 417 */ getInstallCooldownWindow()418 public long getInstallCooldownWindow() { 419 return mInstallCooldownWindow; 420 } 421 422 /** 423 * Is an App-install attributed to the {@link Source}. 424 */ isInstallAttributed()425 public boolean isInstallAttributed() { 426 return mIsInstallAttributed; 427 } 428 429 /** Is Ad Tech Opt-in to Debug Reporting {@link Source}. */ isDebugReporting()430 public boolean isDebugReporting() { 431 return mIsDebugReporting; 432 } 433 434 /** 435 * Returns aggregate filter data string used for aggregation. aggregate filter data json is a 436 * JSONObject in Attribution-Reporting-Register-Source header. Example: 437 * Attribution-Reporting-Register-Source: { // some other fields. "filter_data" : { 438 * "conversion_subdomain": ["electronics.megastore"], "product": ["1234", "2345"], "ctid": 439 * ["id"], ...... } } 440 */ getFilterDataString()441 public String getFilterDataString() { 442 return mFilterDataString; 443 } 444 445 /** 446 * Returns aggregate source string used for aggregation. aggregate source json is a JSONArray. 447 * Example: 448 * [{ 449 * // Generates a "0x159" key piece (low order bits of the key) named 450 * // "campaignCounts" 451 * "id": "campaignCounts", 452 * "key_piece": "0x159", // User saw ad from campaign 345 (out of 511) 453 * }, 454 * { 455 * // Generates a "0x5" key piece (low order bits of the key) named "geoValue" 456 * "id": "geoValue", 457 * // Source-side geo region = 5 (US), out of a possible ~100 regions. 458 * "key_piece": "0x5", 459 * }] 460 */ getAggregateSource()461 public String getAggregateSource() { 462 return mAggregateSource; 463 } 464 465 /** 466 * Returns the current sum of values the source contributed to aggregatable reports. 467 */ getAggregateContributions()468 public int getAggregateContributions() { 469 return mAggregateContributions; 470 } 471 472 /** 473 * Returns the AggregatableAttributionSource object, which is constructed using the aggregate 474 * source string and aggregate filter data string in Source. 475 */ getAggregatableAttributionSource()476 public Optional<AggregatableAttributionSource> getAggregatableAttributionSource() 477 throws JSONException { 478 if (mAggregatableAttributionSource == null) { 479 if (mAggregateSource == null) { 480 mAggregatableAttributionSource = Optional.empty(); 481 return mAggregatableAttributionSource; 482 } 483 JSONObject jsonObject = new JSONObject(mAggregateSource); 484 TreeMap<String, BigInteger> aggregateSourceMap = new TreeMap<>(); 485 for (String key : jsonObject.keySet()) { 486 // Remove "0x" prefix. 487 String hexString = jsonObject.getString(key).substring(2); 488 BigInteger bigInteger = new BigInteger(hexString, 16); 489 aggregateSourceMap.put(key, bigInteger); 490 } 491 AggregatableAttributionSource aggregatableAttributionSource = 492 new AggregatableAttributionSource.Builder() 493 .setAggregatableSource(aggregateSourceMap) 494 .setFilterMap(getFilterData()) 495 .build(); 496 mAggregatableAttributionSource = Optional.of(aggregatableAttributionSource); 497 } 498 499 return mAggregatableAttributionSource; 500 } 501 502 /** Returns the registration id. */ 503 @Nullable getRegistrationId()504 public String getRegistrationId() { 505 return mRegistrationId; 506 } 507 508 /** 509 * Returns the shared aggregation keys of the source as a unique list of strings. Example: 510 * [“campaignCounts”] 511 */ 512 @Nullable getSharedAggregationKeys()513 public String getSharedAggregationKeys() { 514 return mSharedAggregationKeys; 515 } 516 517 /** Returns the install time of the source which is the same value as event time. */ 518 @Nullable getInstallTime()519 public Long getInstallTime() { 520 return mInstallTime; 521 } 522 523 /** 524 * Returns join key that should be matched with trigger's join key at the time of generating 525 * reports. 526 */ 527 @Nullable getDebugJoinKey()528 public String getDebugJoinKey() { 529 return mDebugJoinKey; 530 } 531 532 /** 533 * Returns SHA256 hash of AdID from getAdId() on app registration concatenated with enrollment 534 * ID, to be matched with a web trigger's {@link Trigger#getDebugAdId()} value at the time of 535 * generating reports. 536 */ 537 @Nullable getPlatformAdId()538 public String getPlatformAdId() { 539 return mPlatformAdId; 540 } 541 542 /** 543 * Returns SHA256 hash of AdID from registration response on web registration concatenated with 544 * enrollment ID, to be matched with an app trigger's {@link Trigger#getPlatformAdId()} value at 545 * the time of generating reports. 546 */ 547 @Nullable getDebugAdId()548 public String getDebugAdId() { 549 return mDebugAdId; 550 } 551 552 /** 553 * Indicates whether event report for this source should be generated with the destinations 554 * where the conversion occurred or merge app and web destinations. Set to true of both app and 555 * web destination should be merged into the array of event report. 556 */ getCoarseEventReportDestinations()557 public boolean getCoarseEventReportDestinations() { 558 return mCoarseEventReportDestinations; 559 } 560 561 /** Returns registration origin used to register the source */ getRegistrationOrigin()562 public Uri getRegistrationOrigin() { 563 return mRegistrationOrigin; 564 } 565 566 /** Returns flex event report spec */ 567 @Nullable getFlexEventReportSpec()568 public ReportSpec getFlexEventReportSpec() { 569 return mFlexEventReportSpec; 570 } 571 572 /** See {@link Source#getAppDestinations()} */ setAppDestinations(@ullable List<Uri> appDestinations)573 public void setAppDestinations(@Nullable List<Uri> appDestinations) { 574 mAppDestinations = appDestinations; 575 } 576 577 /** See {@link Source#getWebDestinations()} */ setWebDestinations(@ullable List<Uri> webDestinations)578 public void setWebDestinations(@Nullable List<Uri> webDestinations) { 579 mWebDestinations = webDestinations; 580 } 581 582 /** Set app install attribution to the {@link Source}. */ setInstallAttributed(boolean isInstallAttributed)583 public void setInstallAttributed(boolean isInstallAttributed) { 584 mIsInstallAttributed = isInstallAttributed; 585 } 586 587 /** 588 * @return if it's a derived source, returns the ID of the source it was created from. If it is 589 * null, it is an original source. 590 */ 591 @Nullable getParentId()592 public String getParentId() { 593 return mParentId; 594 } 595 596 /** 597 * Set the status. 598 */ setStatus(@tatus int status)599 public void setStatus(@Status int status) { 600 mStatus = status; 601 } 602 603 /** 604 * Set the aggregate contributions value. 605 */ setAggregateContributions(int aggregateContributions)606 public void setAggregateContributions(int aggregateContributions) { 607 mAggregateContributions = aggregateContributions; 608 } 609 610 /** 611 * Generates AggregatableFilterData from aggregate filter string in Source, including an entry 612 * for source type. 613 */ getFilterData()614 public FilterMap getFilterData() throws JSONException { 615 if (mFilterData != null) { 616 return mFilterData; 617 } 618 619 if (mFilterDataString == null || mFilterDataString.isEmpty()) { 620 mFilterData = new FilterMap.Builder().build(); 621 } else { 622 mFilterData = 623 new FilterMap.Builder() 624 .buildFilterData(new JSONObject(mFilterDataString)) 625 .build(); 626 } 627 mFilterData 628 .getAttributionFilterMap() 629 .put("source_type", Collections.singletonList(mSourceType.getValue())); 630 return mFilterData; 631 } 632 633 /** Returns true if the source has app destination(s), false otherwise. */ hasAppDestinations()634 public boolean hasAppDestinations() { 635 return mAppDestinations != null && mAppDestinations.size() > 0; 636 } 637 638 /** Returns true if the source has web destination(s), false otherwise. */ hasWebDestinations()639 public boolean hasWebDestinations() { 640 return mWebDestinations != null && mWebDestinations.size() > 0; 641 } 642 areEqualNullableDestinations(List<Uri> destinations, List<Uri> otherDestinations)643 private static boolean areEqualNullableDestinations(List<Uri> destinations, 644 List<Uri> otherDestinations) { 645 if (destinations == null && otherDestinations == null) { 646 return true; 647 } else if (destinations == null || otherDestinations == null) { 648 return false; 649 } else { 650 return ImmutableMultiset.copyOf(destinations).equals( 651 ImmutableMultiset.copyOf(otherDestinations)); 652 } 653 } 654 655 /** 656 * Builder for {@link Source}. 657 */ 658 public static final class Builder { 659 private final Source mBuilding; Builder()660 public Builder() { 661 mBuilding = new Source(); 662 } 663 664 /** 665 * Copy builder. 666 * 667 * @param copyFrom copy from source 668 * @return copied source 669 */ from(Source copyFrom)670 public static Builder from(Source copyFrom) { 671 Builder builder = new Builder(); 672 builder.setId(copyFrom.mId); 673 builder.setRegistrationId(copyFrom.mRegistrationId); 674 builder.setAggregateSource(copyFrom.mAggregateSource); 675 builder.setExpiryTime(copyFrom.mExpiryTime); 676 builder.setAppDestinations(copyFrom.mAppDestinations); 677 builder.setWebDestinations(copyFrom.mWebDestinations); 678 builder.setSharedAggregationKeys(copyFrom.mSharedAggregationKeys); 679 builder.setEventId(copyFrom.mEventId); 680 builder.setRegistrant(copyFrom.mRegistrant); 681 builder.setEventTime(copyFrom.mEventTime); 682 builder.setPublisher(copyFrom.mPublisher); 683 builder.setPublisherType(copyFrom.mPublisherType); 684 builder.setInstallCooldownWindow(copyFrom.mInstallCooldownWindow); 685 builder.setInstallAttributed(copyFrom.mIsInstallAttributed); 686 builder.setInstallAttributionWindow(copyFrom.mInstallAttributionWindow); 687 builder.setSourceType(copyFrom.mSourceType); 688 builder.setAdIdPermission(copyFrom.mAdIdPermission); 689 builder.setAggregateContributions(copyFrom.mAggregateContributions); 690 builder.setArDebugPermission(copyFrom.mArDebugPermission); 691 builder.setAttributionMode(copyFrom.mAttributionMode); 692 builder.setDebugKey(copyFrom.mDebugKey); 693 builder.setEventReportDedupKeys(copyFrom.mEventReportDedupKeys); 694 builder.setAggregateReportDedupKeys(copyFrom.mAggregateReportDedupKeys); 695 builder.setEventReportWindow(copyFrom.mEventReportWindow); 696 builder.setAggregatableReportWindow(copyFrom.mAggregatableReportWindow); 697 builder.setEnrollmentId(copyFrom.mEnrollmentId); 698 builder.setFilterData(copyFrom.mFilterDataString); 699 builder.setInstallTime(copyFrom.mInstallTime); 700 builder.setIsDebugReporting(copyFrom.mIsDebugReporting); 701 builder.setPriority(copyFrom.mPriority); 702 builder.setStatus(copyFrom.mStatus); 703 builder.setDebugJoinKey(copyFrom.mDebugJoinKey); 704 builder.setPlatformAdId(copyFrom.mPlatformAdId); 705 builder.setDebugAdId(copyFrom.mDebugAdId); 706 builder.setRegistrationOrigin(copyFrom.mRegistrationOrigin); 707 builder.setFlexEventReportSpec(copyFrom.mFlexEventReportSpec); 708 builder.setCoarseEventReportDestinations(copyFrom.mCoarseEventReportDestinations); 709 return builder; 710 } 711 712 /** See {@link Source#getId()}. */ 713 @NonNull setId(@onNull String id)714 public Builder setId(@NonNull String id) { 715 mBuilding.mId = id; 716 return this; 717 } 718 719 /** See {@link Source#getEventId()}. */ 720 @NonNull setEventId(UnsignedLong eventId)721 public Builder setEventId(UnsignedLong eventId) { 722 mBuilding.mEventId = eventId; 723 return this; 724 } 725 726 /** See {@link Source#getPublisher()}. */ 727 @NonNull setPublisher(@onNull Uri publisher)728 public Builder setPublisher(@NonNull Uri publisher) { 729 Validation.validateUri(publisher); 730 mBuilding.mPublisher = publisher; 731 return this; 732 } 733 734 /** See {@link Source#getPublisherType()}. */ 735 @NonNull setPublisherType(@ventSurfaceType int publisherType)736 public Builder setPublisherType(@EventSurfaceType int publisherType) { 737 mBuilding.mPublisherType = publisherType; 738 return this; 739 } 740 741 /** See {@link Source#getAppDestinations()}. */ 742 @NonNull setAppDestinations(@ullable List<Uri> appDestinations)743 public Builder setAppDestinations(@Nullable List<Uri> appDestinations) { 744 Optional.ofNullable(appDestinations).ifPresent(uris -> { 745 Validation.validateNotEmpty(uris); 746 if (uris.size() > 1) { 747 throw new IllegalArgumentException("Received more than one app destination"); 748 } 749 Validation.validateUri(uris.toArray(new Uri[0])); 750 }); 751 mBuilding.mAppDestinations = appDestinations; 752 return this; 753 } 754 755 /** See {@link Source#getWebDestinations()}. */ 756 @NonNull setWebDestinations(@ullable List<Uri> webDestinations)757 public Builder setWebDestinations(@Nullable List<Uri> webDestinations) { 758 Optional.ofNullable(webDestinations).ifPresent(uris -> { 759 Validation.validateNotEmpty(uris); 760 Validation.validateUri(uris.toArray(new Uri[0])); 761 }); 762 mBuilding.mWebDestinations = webDestinations; 763 return this; 764 } 765 766 /** See {@link Source#getEnrollmentId()}. */ 767 @NonNull setEnrollmentId(@onNull String enrollmentId)768 public Builder setEnrollmentId(@NonNull String enrollmentId) { 769 mBuilding.mEnrollmentId = enrollmentId; 770 return this; 771 } 772 773 /** See {@link Source#hasAdIdPermission()} */ setAdIdPermission(boolean adIdPermission)774 public Source.Builder setAdIdPermission(boolean adIdPermission) { 775 mBuilding.mAdIdPermission = adIdPermission; 776 return this; 777 } 778 779 /** See {@link Source#hasArDebugPermission()} */ setArDebugPermission(boolean arDebugPermission)780 public Source.Builder setArDebugPermission(boolean arDebugPermission) { 781 mBuilding.mArDebugPermission = arDebugPermission; 782 return this; 783 } 784 785 /** See {@link Source#getEventId()}. */ 786 @NonNull setEventTime(long eventTime)787 public Builder setEventTime(long eventTime) { 788 mBuilding.mEventTime = eventTime; 789 return this; 790 } 791 792 /** 793 * See {@link Source#getExpiryTime()}. 794 */ setExpiryTime(long expiryTime)795 public Builder setExpiryTime(long expiryTime) { 796 mBuilding.mExpiryTime = expiryTime; 797 return this; 798 } 799 800 /** 801 * See {@link Source#getEventReportWindow()}. 802 */ setEventReportWindow(long eventReportWindow)803 public Builder setEventReportWindow(long eventReportWindow) { 804 mBuilding.mEventReportWindow = eventReportWindow; 805 return this; 806 } 807 808 /** 809 * See {@link Source#getAggregatableReportWindow()}. 810 */ setAggregatableReportWindow(long aggregateReportWindow)811 public Builder setAggregatableReportWindow(long aggregateReportWindow) { 812 mBuilding.mAggregatableReportWindow = aggregateReportWindow; 813 return this; 814 } 815 816 /** See {@link Source#getPriority()}. */ 817 @NonNull setPriority(long priority)818 public Builder setPriority(long priority) { 819 mBuilding.mPriority = priority; 820 return this; 821 } 822 823 /** See {@link Source#getDebugKey()}. */ setDebugKey(@ullable UnsignedLong debugKey)824 public Builder setDebugKey(@Nullable UnsignedLong debugKey) { 825 mBuilding.mDebugKey = debugKey; 826 return this; 827 } 828 829 /** See {@link Source#isDebugReporting()}. */ setIsDebugReporting(boolean isDebugReporting)830 public Builder setIsDebugReporting(boolean isDebugReporting) { 831 mBuilding.mIsDebugReporting = isDebugReporting; 832 return this; 833 } 834 835 /** See {@link Source#getSourceType()}. */ 836 @NonNull setSourceType(@onNull SourceType sourceType)837 public Builder setSourceType(@NonNull SourceType sourceType) { 838 Validation.validateNonNull(sourceType); 839 mBuilding.mSourceType = sourceType; 840 return this; 841 } 842 843 /** See {@link Source#getEventReportDedupKeys()}. */ 844 @NonNull setEventReportDedupKeys(@ullable List<UnsignedLong> mEventReportDedupKeys)845 public Builder setEventReportDedupKeys(@Nullable List<UnsignedLong> mEventReportDedupKeys) { 846 mBuilding.mEventReportDedupKeys = mEventReportDedupKeys; 847 return this; 848 } 849 850 /** See {@link Source#getAggregateReportDedupKeys()}. */ 851 @NonNull setAggregateReportDedupKeys( @onNull List<UnsignedLong> mAggregateReportDedupKeys)852 public Builder setAggregateReportDedupKeys( 853 @NonNull List<UnsignedLong> mAggregateReportDedupKeys) { 854 mBuilding.mAggregateReportDedupKeys = mAggregateReportDedupKeys; 855 return this; 856 } 857 858 /** See {@link Source#getStatus()}. */ 859 @NonNull setStatus(@tatus int status)860 public Builder setStatus(@Status int status) { 861 mBuilding.mStatus = status; 862 return this; 863 } 864 865 /** See {@link Source#getRegistrant()} */ 866 @NonNull setRegistrant(@onNull Uri registrant)867 public Builder setRegistrant(@NonNull Uri registrant) { 868 Validation.validateUri(registrant); 869 mBuilding.mRegistrant = registrant; 870 return this; 871 } 872 873 /** See {@link Source#getAttributionMode()} */ 874 @NonNull setAttributionMode(@ttributionMode int attributionMode)875 public Builder setAttributionMode(@AttributionMode int attributionMode) { 876 mBuilding.mAttributionMode = attributionMode; 877 return this; 878 } 879 880 /** See {@link Source#getInstallAttributionWindow()} */ 881 @NonNull setInstallAttributionWindow(long installAttributionWindow)882 public Builder setInstallAttributionWindow(long installAttributionWindow) { 883 mBuilding.mInstallAttributionWindow = installAttributionWindow; 884 return this; 885 } 886 887 /** See {@link Source#getInstallCooldownWindow()} */ 888 @NonNull setInstallCooldownWindow(long installCooldownWindow)889 public Builder setInstallCooldownWindow(long installCooldownWindow) { 890 mBuilding.mInstallCooldownWindow = installCooldownWindow; 891 return this; 892 } 893 894 /** See {@link Source#isInstallAttributed()} */ 895 @NonNull setInstallAttributed(boolean installAttributed)896 public Builder setInstallAttributed(boolean installAttributed) { 897 mBuilding.mIsInstallAttributed = installAttributed; 898 return this; 899 } 900 901 /** See {@link Source#getFilterDataString()}. */ setFilterData(@ullable String filterMap)902 public Builder setFilterData(@Nullable String filterMap) { 903 mBuilding.mFilterDataString = filterMap; 904 return this; 905 } 906 907 /** See {@link Source#getAggregateSource()} */ 908 @NonNull setAggregateSource(@ullable String aggregateSource)909 public Builder setAggregateSource(@Nullable String aggregateSource) { 910 mBuilding.mAggregateSource = aggregateSource; 911 return this; 912 } 913 914 /** See {@link Source#getAggregateContributions()} */ 915 @NonNull setAggregateContributions(int aggregateContributions)916 public Builder setAggregateContributions(int aggregateContributions) { 917 mBuilding.mAggregateContributions = aggregateContributions; 918 return this; 919 } 920 921 /** See {@link Source#getRegistrationId()} */ 922 @NonNull setRegistrationId(@ullable String registrationId)923 public Builder setRegistrationId(@Nullable String registrationId) { 924 mBuilding.mRegistrationId = registrationId; 925 return this; 926 } 927 928 /** See {@link Source#getSharedAggregationKeys()} */ 929 @NonNull setSharedAggregationKeys(@ullable String sharedAggregationKeys)930 public Builder setSharedAggregationKeys(@Nullable String sharedAggregationKeys) { 931 mBuilding.mSharedAggregationKeys = sharedAggregationKeys; 932 return this; 933 } 934 935 /** See {@link Source#getInstallTime()} */ 936 @NonNull setInstallTime(@ullable Long installTime)937 public Builder setInstallTime(@Nullable Long installTime) { 938 mBuilding.mInstallTime = installTime; 939 return this; 940 } 941 942 /** See {@link Source#getParentId()} */ 943 @NonNull setParentId(@ullable String parentId)944 public Builder setParentId(@Nullable String parentId) { 945 mBuilding.mParentId = parentId; 946 return this; 947 } 948 949 /** See {@link Source#getAggregatableAttributionSource()} */ 950 @NonNull setAggregatableAttributionSource( @ullable AggregatableAttributionSource aggregatableAttributionSource)951 public Builder setAggregatableAttributionSource( 952 @Nullable AggregatableAttributionSource aggregatableAttributionSource) { 953 mBuilding.mAggregatableAttributionSource = 954 Optional.ofNullable(aggregatableAttributionSource); 955 return this; 956 } 957 958 /** See {@link Source#getDebugJoinKey()} */ 959 @NonNull setDebugJoinKey(@ullable String debugJoinKey)960 public Builder setDebugJoinKey(@Nullable String debugJoinKey) { 961 mBuilding.mDebugJoinKey = debugJoinKey; 962 return this; 963 } 964 965 /** See {@link Source#getPlatformAdId()} */ 966 @NonNull setPlatformAdId(@ullable String platformAdId)967 public Builder setPlatformAdId(@Nullable String platformAdId) { 968 mBuilding.mPlatformAdId = platformAdId; 969 return this; 970 } 971 972 /** See {@link Source#getDebugAdId()} */ 973 @NonNull setDebugAdId(@ullable String debugAdId)974 public Builder setDebugAdId(@Nullable String debugAdId) { 975 mBuilding.mDebugAdId = debugAdId; 976 return this; 977 } 978 979 /** See {@link Source#getRegistrationOrigin()} ()} */ 980 @NonNull setRegistrationOrigin(Uri registrationOrigin)981 public Builder setRegistrationOrigin(Uri registrationOrigin) { 982 mBuilding.mRegistrationOrigin = registrationOrigin; 983 return this; 984 } 985 986 /** See {@link Source#getFlexEventReportSpec()} */ 987 @NonNull setFlexEventReportSpec(@ullable ReportSpec flexEventReportSpec)988 public Builder setFlexEventReportSpec(@Nullable ReportSpec flexEventReportSpec) { 989 mBuilding.mFlexEventReportSpec = flexEventReportSpec; 990 return this; 991 } 992 993 /** See {@link Source#getCoarseEventReportDestinations()} */ 994 @NonNull setCoarseEventReportDestinations(boolean coarseEventReportDestinations)995 public Builder setCoarseEventReportDestinations(boolean coarseEventReportDestinations) { 996 mBuilding.mCoarseEventReportDestinations = coarseEventReportDestinations; 997 return this; 998 } 999 1000 /** Build the {@link Source}. */ 1001 @NonNull build()1002 public Source build() { 1003 Validation.validateNonNull( 1004 mBuilding.mPublisher, 1005 mBuilding.mEnrollmentId, 1006 mBuilding.mRegistrant, 1007 mBuilding.mSourceType, 1008 mBuilding.mAggregateReportDedupKeys, 1009 mBuilding.mEventReportDedupKeys, 1010 mBuilding.mRegistrationOrigin); 1011 1012 return mBuilding; 1013 } 1014 } 1015 } 1016