• 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.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