• 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.aggregation;
18 
19 import static com.android.adservices.service.measurement.aggregation.AggregatePayloadGenerator.POST_FLEXIBLE_CONTRIBUTION_FILTERING_API_VERSION;
20 
21 import android.annotation.IntDef;
22 import android.annotation.NonNull;
23 import android.net.Uri;
24 
25 import androidx.annotation.Nullable;
26 
27 import com.android.adservices.LoggerFactory;
28 import com.android.adservices.service.AdServicesConfig;
29 import com.android.adservices.service.Flags;
30 import com.android.adservices.service.measurement.EventSurfaceType;
31 import com.android.adservices.service.measurement.Trigger;
32 import com.android.adservices.service.measurement.util.UnsignedLong;
33 
34 import org.json.JSONArray;
35 import org.json.JSONException;
36 import org.json.JSONObject;
37 
38 import java.lang.annotation.Retention;
39 import java.lang.annotation.RetentionPolicy;
40 import java.util.ArrayList;
41 import java.util.Collections;
42 import java.util.List;
43 import java.util.Objects;
44 import java.util.UUID;
45 
46 /**
47  * Class that contains all the real data needed after aggregation, it is not encrypted.
48  */
49 public class AggregateReport {
50     static final String OPERATION = "operation";
51     static final String HISTOGRAM = "histogram";
52     static final String DATA = "data";
53 
54     private String mId;
55     private Uri mPublisher;
56     private Uri mAttributionDestination;
57     @Nullable private Long mSourceRegistrationTime;
58     private long mScheduledReportTime;   // triggerTime + random([10min, 1hour])
59     private String mEnrollmentId;
60     private String mDebugCleartextPayload;
61     private AggregateAttributionData mAggregateAttributionData;
62     private @Status int mStatus;
63     private @DebugReportStatus int mDebugReportStatus;
64     private String mApiVersion;
65     @Nullable private UnsignedLong mSourceDebugKey;
66     @Nullable private UnsignedLong mTriggerDebugKey;
67     private String mSourceId;
68     private String mTriggerId;
69     private UnsignedLong mDedupKey;
70     private Uri mRegistrationOrigin;
71     private Uri mAggregationCoordinatorOrigin;
72     private boolean mIsFakeReport;
73     @Nullable private String mTriggerContextId;
74     private long mTriggerTime;
75     private String mApi;
76     @Nullable private Integer mAggregatableFilteringIdMaxBytes;
77 
78     @IntDef(value = {Status.PENDING, Status.DELIVERED, Status.MARKED_TO_DELETE})
79     @Retention(RetentionPolicy.SOURCE)
80     public @interface Status {
81         int PENDING = 0;
82         int DELIVERED = 1;
83         int MARKED_TO_DELETE = 2;
84     }
85 
86     @IntDef(
87             value = {
88                 DebugReportStatus.NONE,
89                 DebugReportStatus.PENDING,
90                 DebugReportStatus.DELIVERED,
91             })
92     @Retention(RetentionPolicy.SOURCE)
93     public @interface DebugReportStatus {
94         int NONE = 0;
95         int PENDING = 1;
96         int DELIVERED = 2;
97     }
98 
AggregateReport()99     private AggregateReport() {
100         mId = null;
101         mPublisher = null;
102         mAttributionDestination = null;
103         mSourceRegistrationTime = null;
104         mScheduledReportTime = 0L;
105         mEnrollmentId = null;
106         mDebugCleartextPayload = null;
107         mAggregateAttributionData = null;
108         mStatus = Status.PENDING;
109         mDebugReportStatus = DebugReportStatus.NONE;
110         mSourceDebugKey = null;
111         mTriggerDebugKey = null;
112         mDedupKey = null;
113         mRegistrationOrigin = null;
114         mAggregationCoordinatorOrigin = null;
115         mTriggerContextId = null;
116         mTriggerTime = 0L;
117         mApi = null;
118         mAggregatableFilteringIdMaxBytes = null;
119     }
120 
121     @Override
equals(Object obj)122     public boolean equals(Object obj) {
123         if (!(obj instanceof AggregateReport)) {
124             return false;
125         }
126         AggregateReport aggregateReport = (AggregateReport) obj;
127         return Objects.equals(mPublisher, aggregateReport.mPublisher)
128                 && Objects.equals(mAttributionDestination, aggregateReport.mAttributionDestination)
129                 && Objects.equals(mSourceRegistrationTime, aggregateReport.mSourceRegistrationTime)
130                 && mScheduledReportTime == aggregateReport.mScheduledReportTime
131                 && Objects.equals(mEnrollmentId, aggregateReport.mEnrollmentId)
132                 && Objects.equals(mDebugCleartextPayload, aggregateReport.mDebugCleartextPayload)
133                 && Objects.equals(
134                         mAggregateAttributionData, aggregateReport.mAggregateAttributionData)
135                 && mStatus == aggregateReport.mStatus
136                 && mDebugReportStatus == aggregateReport.mDebugReportStatus
137                 && Objects.equals(mApiVersion, aggregateReport.mApiVersion)
138                 && Objects.equals(mSourceDebugKey, aggregateReport.mSourceDebugKey)
139                 && Objects.equals(mTriggerDebugKey, aggregateReport.mTriggerDebugKey)
140                 && Objects.equals(mSourceId, aggregateReport.mSourceId)
141                 && Objects.equals(mTriggerId, aggregateReport.mTriggerId)
142                 && Objects.equals(mDedupKey, aggregateReport.mDedupKey)
143                 && Objects.equals(mRegistrationOrigin, aggregateReport.mRegistrationOrigin)
144                 && Objects.equals(
145                         mAggregationCoordinatorOrigin,
146                         aggregateReport.mAggregationCoordinatorOrigin)
147                 && mIsFakeReport == aggregateReport.mIsFakeReport
148                 && Objects.equals(mTriggerContextId, aggregateReport.mTriggerContextId)
149                 && mTriggerTime == aggregateReport.mTriggerTime
150                 && Objects.equals(mApi, aggregateReport.mApi)
151                 && Objects.equals(
152                         mAggregatableFilteringIdMaxBytes,
153                         aggregateReport.mAggregatableFilteringIdMaxBytes);
154     }
155 
156     @Override
hashCode()157     public int hashCode() {
158         return Objects.hash(
159                 mId,
160                 mPublisher,
161                 mAttributionDestination,
162                 mSourceRegistrationTime,
163                 mScheduledReportTime,
164                 mEnrollmentId,
165                 mDebugCleartextPayload,
166                 mAggregateAttributionData,
167                 mStatus,
168                 mDebugReportStatus,
169                 mSourceDebugKey,
170                 mTriggerDebugKey,
171                 mSourceId,
172                 mTriggerId,
173                 mDedupKey,
174                 mRegistrationOrigin,
175                 mAggregationCoordinatorOrigin,
176                 mIsFakeReport,
177                 mTriggerContextId,
178                 mTriggerTime,
179                 mApi,
180                 mAggregatableFilteringIdMaxBytes);
181     }
182 
183     /**
184      * Unique identifier for the {@link AggregateReport}.
185      */
getId()186     public String getId() {
187         return mId;
188     }
189 
190     /**
191      * Uri for publisher of this source, primarily an App.
192      */
getPublisher()193     public Uri getPublisher() {
194         return mPublisher;
195     }
196 
197     /**
198      * Uri for attribution destination of source.
199      */
getAttributionDestination()200     public Uri getAttributionDestination() {
201         return mAttributionDestination;
202     }
203 
204     /** Source registration time. */
205     @Nullable
getSourceRegistrationTime()206     public Long getSourceRegistrationTime() {
207         return mSourceRegistrationTime;
208     }
209 
210     /**
211      * Scheduled report time for aggregate report .
212      */
getScheduledReportTime()213     public long getScheduledReportTime() {
214         return mScheduledReportTime;
215     }
216 
217     /**
218      * Ad-tech enrollment ID.
219      */
getEnrollmentId()220     public String getEnrollmentId() {
221         return mEnrollmentId;
222     }
223 
224     /**
225      * Unencrypted aggregate payload string, convert from List of AggregateHistogramContribution.
226      */
getDebugCleartextPayload()227     public String getDebugCleartextPayload() {
228         return mDebugCleartextPayload;
229     }
230 
231     /** Source Debug Key */
232     @Nullable
getSourceDebugKey()233     public UnsignedLong getSourceDebugKey() {
234         return mSourceDebugKey;
235     }
236 
237     /** Trigger Debug Key */
238     @Nullable
getTriggerDebugKey()239     public UnsignedLong getTriggerDebugKey() {
240         return mTriggerDebugKey;
241     }
242 
243     /**
244      * Contains the data specific to the aggregate report.
245      *
246      * @deprecated use {@link #getDebugCleartextPayload()} instead
247      */
248     @Deprecated
getAggregateAttributionData()249     public AggregateAttributionData getAggregateAttributionData() {
250         return mAggregateAttributionData;
251     }
252 
253     /**
254      * Current {@link Status} of the report.
255      */
getStatus()256     public @Status int getStatus() {
257         return mStatus;
258     }
259 
260     /** Current {@link DebugReportStatus} of the report. */
getDebugReportStatus()261     public @DebugReportStatus int getDebugReportStatus() {
262         return mDebugReportStatus;
263     }
264 
265     /**
266      * Api version when the report was issued.
267      */
getApiVersion()268     public String getApiVersion() {
269         return mApiVersion;
270     }
271 
272     /** Deduplication key assigned to theis aggregate report. */
273     @Nullable
getDedupKey()274     public UnsignedLong getDedupKey() {
275         return mDedupKey;
276     }
277 
278     /** Returns registration origin used to register the source */
getRegistrationOrigin()279     public Uri getRegistrationOrigin() {
280         return mRegistrationOrigin;
281     }
282 
283     /** Returns coordinator origin for aggregatable reports */
getAggregationCoordinatorOrigin()284     public Uri getAggregationCoordinatorOrigin() {
285         return mAggregationCoordinatorOrigin;
286     }
287 
288     /** Is the report a null report. */
isFakeReport()289     public boolean isFakeReport() {
290         return mIsFakeReport;
291     }
292 
293     /** Returns the trigger's context id. */
294     @Nullable
getTriggerContextId()295     public String getTriggerContextId() {
296         return mTriggerContextId;
297     }
298 
299     /** TriggerTime of the associated {@link Trigger}. */
getTriggerTime()300     public long getTriggerTime() {
301         return mTriggerTime;
302     }
303 
304     /** Returns the aggregate report api. */
getApi()305     public String getApi() {
306         return mApi;
307     }
308 
309     /** Returns the aggregatable filtering id max bytes. */
310     @Nullable
getAggregatableFilteringIdMaxBytes()311     public Integer getAggregatableFilteringIdMaxBytes() {
312         return mAggregatableFilteringIdMaxBytes;
313     }
314 
315     /** Returns if the report for this Trigger should be sent immediately or with a delay. */
isDelayed(Trigger trigger, Flags flags)316     public static boolean isDelayed(Trigger trigger, Flags flags) {
317         boolean isNonNullTriggerContextId = trigger.getTriggerContextId() != null;
318         boolean isNonNullFilteringIdAndNonDefaultFilteringIdMaxBytes =
319                 flags.getMeasurementEnableFlexibleContributionFiltering()
320                         && trigger.getAggregatableFilteringIdMaxBytes() != null
321                         && trigger.getAggregatableFilteringIdMaxBytes()
322                         != Flags.MEASUREMENT_DEFAULT_FILTERING_ID_MAX_BYTES;
323         if (isNonNullTriggerContextId || isNonNullFilteringIdAndNonDefaultFilteringIdMaxBytes) {
324             return false;
325         }
326         return true;
327     }
328 
329     /**
330      * Generates String for debugCleartextPayload. JSON for format : { "operation": "histogram",
331      * "data": [{ "bucket": 1369, "value": 32768 }, { "bucket": 3461, "value": 1664 }] }
332      */
333     @NonNull
generateDebugPayload(List<AggregateHistogramContribution> contributions)334     public static String generateDebugPayload(List<AggregateHistogramContribution> contributions)
335             throws JSONException {
336         JSONArray jsonArray = new JSONArray();
337         for (AggregateHistogramContribution contribution : contributions) {
338             jsonArray.put(contribution.toJSONObject());
339         }
340         JSONObject debugPayload = new JSONObject();
341         debugPayload.put(OPERATION, HISTOGRAM);
342         debugPayload.put(DATA, jsonArray);
343         return debugPayload.toString();
344     }
345 
346     /**
347      * It deserializes the debug cleartext payload into {@link AggregateHistogramContribution}s.
348      *
349      * @return list of {@link AggregateHistogramContribution}s
350      */
351     @NonNull
extractAggregateHistogramContributions()352     public List<AggregateHistogramContribution> extractAggregateHistogramContributions() {
353         try {
354             ArrayList<AggregateHistogramContribution> aggregateHistogramContributions =
355                     new ArrayList<>();
356             JSONObject debugCleartextPayload = new JSONObject(mDebugCleartextPayload);
357             JSONArray contributionsArray = debugCleartextPayload.getJSONArray(DATA);
358             for (int i = 0; i < contributionsArray.length(); i++) {
359                 AggregateHistogramContribution aggregateHistogramContribution =
360                         new AggregateHistogramContribution.Builder()
361                                 .fromJsonObject(contributionsArray.getJSONObject(i));
362                 aggregateHistogramContributions.add(aggregateHistogramContribution);
363             }
364             return aggregateHistogramContributions;
365         } catch (JSONException e) {
366             LoggerFactory.getMeasurementLogger()
367                     .e(e, "Failed to parse contributions on Aggregate report.");
368             return Collections.emptyList();
369         }
370     }
371 
372     /**
373      * Source ID. Can be null for trigger verbose aggregate debug reports, where no source is
374      * involved, e.g. trigger-no-matching-source or source-destination-limit (no source in DB).
375      */
376     @Nullable
getSourceId()377     public String getSourceId() {
378         return mSourceId;
379     }
380 
381     /**
382      * Trigger ID. Can be null for source verbose aggregate debug reports, where no trigger is
383      * involved, e.g. source-success.
384      */
385     @Nullable
getTriggerId()386     public String getTriggerId() {
387         return mTriggerId;
388     }
389 
390     /**
391      * Builder for {@link AggregateReport}.
392      */
393     public static final class Builder {
394         private final AggregateReport mAttributionReport;
395 
Builder()396         public Builder() {
397             mAttributionReport = new AggregateReport();
398         }
399 
400         /**
401          * See {@link AggregateReport#getId()}.
402          */
setId(String id)403         public Builder setId(String id) {
404             mAttributionReport.mId = id;
405             return this;
406         }
407 
408         /**
409          * See {@link AggregateReport#getPublisher()}.
410          */
setPublisher(Uri publisher)411         public Builder setPublisher(Uri publisher) {
412             mAttributionReport.mPublisher = publisher;
413             return this;
414         }
415 
416         /**
417          * See {@link AggregateReport#getAttributionDestination()}.
418          */
setAttributionDestination(Uri attributionDestination)419         public Builder setAttributionDestination(Uri attributionDestination) {
420             mAttributionReport.mAttributionDestination = attributionDestination;
421             return this;
422         }
423 
424         /** See {@link AggregateReport#getSourceRegistrationTime()}. */
setSourceRegistrationTime(@ullable Long sourceRegistrationTime)425         public Builder setSourceRegistrationTime(@Nullable Long sourceRegistrationTime) {
426             mAttributionReport.mSourceRegistrationTime = sourceRegistrationTime;
427             return this;
428         }
429 
430         /**
431          * See {@link AggregateReport#getScheduledReportTime()}.
432          */
setScheduledReportTime(long scheduledReportTime)433         public Builder setScheduledReportTime(long scheduledReportTime) {
434             mAttributionReport.mScheduledReportTime = scheduledReportTime;
435             return this;
436         }
437 
438         /**
439          * See {@link AggregateReport#getEnrollmentId()}.
440          */
setEnrollmentId(String enrollmentId)441         public Builder setEnrollmentId(String enrollmentId) {
442             mAttributionReport.mEnrollmentId = enrollmentId;
443             return this;
444         }
445 
446         /**
447          * See {@link AggregateReport#getDebugCleartextPayload()}.
448          */
setDebugCleartextPayload(String debugCleartextPayload)449         public Builder setDebugCleartextPayload(String debugCleartextPayload) {
450             mAttributionReport.mDebugCleartextPayload = debugCleartextPayload;
451             return this;
452         }
453 
454         /**
455          * See {@link AggregateReport#getAggregateAttributionData()}.
456          *
457          * @deprecated use {@link #getDebugCleartextPayload()} instead
458          */
459         @Deprecated
setAggregateAttributionData( AggregateAttributionData aggregateAttributionData)460         public Builder setAggregateAttributionData(
461                 AggregateAttributionData aggregateAttributionData) {
462             mAttributionReport.mAggregateAttributionData = aggregateAttributionData;
463             return this;
464         }
465 
466         /**
467          * See {@link AggregateReport#getStatus()}
468          */
setStatus(@tatus int status)469         public Builder setStatus(@Status int status) {
470             mAttributionReport.mStatus = status;
471             return this;
472         }
473 
474         /** See {@link AggregateReport#getDebugReportStatus()} */
setDebugReportStatus(@ebugReportStatus int debugReportStatus)475         public Builder setDebugReportStatus(@DebugReportStatus int debugReportStatus) {
476             mAttributionReport.mDebugReportStatus = debugReportStatus;
477             return this;
478         }
479 
480         /**
481          * See {@link AggregateReport#getApiVersion()}
482          */
setApiVersion(String version)483         public Builder setApiVersion(String version) {
484             mAttributionReport.mApiVersion = version;
485             return this;
486         }
487 
488         /** See {@link AggregateReport#getSourceDebugKey()} */
setSourceDebugKey(UnsignedLong sourceDebugKey)489         public Builder setSourceDebugKey(UnsignedLong sourceDebugKey) {
490             mAttributionReport.mSourceDebugKey = sourceDebugKey;
491             return this;
492         }
493 
494         /** See {@link AggregateReport#getTriggerDebugKey()} */
setTriggerDebugKey(UnsignedLong triggerDebugKey)495         public Builder setTriggerDebugKey(UnsignedLong triggerDebugKey) {
496             mAttributionReport.mTriggerDebugKey = triggerDebugKey;
497             return this;
498         }
499 
500         /** See {@link AggregateReport#getSourceId()} */
setSourceId(String sourceId)501         public Builder setSourceId(String sourceId) {
502             mAttributionReport.mSourceId = sourceId;
503             return this;
504         }
505 
506         /** See {@link AggregateReport#getTriggerId()} */
setTriggerId(String triggerId)507         public Builder setTriggerId(String triggerId) {
508             mAttributionReport.mTriggerId = triggerId;
509             return this;
510         }
511 
512         /** See {@link AggregateReport#getDedupKey()} */
513         @NonNull
setDedupKey(@ullable UnsignedLong dedupKey)514         public Builder setDedupKey(@Nullable UnsignedLong dedupKey) {
515             mAttributionReport.mDedupKey = dedupKey;
516             return this;
517         }
518 
519         /** See {@link AggregateReport#getRegistrationOrigin()} */
520         @NonNull
setRegistrationOrigin(Uri registrationOrigin)521         public Builder setRegistrationOrigin(Uri registrationOrigin) {
522             mAttributionReport.mRegistrationOrigin = registrationOrigin;
523             return this;
524         }
525 
526         /** See {@link AggregateReport#getAggregationCoordinatorOrigin()} */
setAggregationCoordinatorOrigin(Uri aggregationCoordinatorOrigin)527         public Builder setAggregationCoordinatorOrigin(Uri aggregationCoordinatorOrigin) {
528             mAttributionReport.mAggregationCoordinatorOrigin = aggregationCoordinatorOrigin;
529             return this;
530         }
531 
532         /** See {@link AggregateReport#isFakeReport()} */
setIsFakeReport(boolean isFakeReport)533         public Builder setIsFakeReport(boolean isFakeReport) {
534             mAttributionReport.mIsFakeReport = isFakeReport;
535             return this;
536         }
537 
538         /** See {@link AggregateReport#getTriggerContextId()} */
setTriggerContextId(@ullable String triggerContextId)539         public Builder setTriggerContextId(@Nullable String triggerContextId) {
540             mAttributionReport.mTriggerContextId = triggerContextId;
541             return this;
542         }
543 
544         /** See {@link AggregateReport#getTriggerTime()} */
setTriggerTime(long triggerTime)545         public Builder setTriggerTime(long triggerTime) {
546             mAttributionReport.mTriggerTime = triggerTime;
547             return this;
548         }
549 
550         /** See {@link AggregateReport#getApi()} */
setApi(@onNull String api)551         public Builder setApi(@NonNull String api) {
552             mAttributionReport.mApi = api;
553             return this;
554         }
555 
556         /** See {@link AggregateReport#getAggregatableFilteringIdMaxBytes()} */
setAggregatableFilteringIdMaxBytes( @ullable Integer aggregatableFilteringIdMaxBytes)557         public Builder setAggregatableFilteringIdMaxBytes(
558                 @Nullable Integer aggregatableFilteringIdMaxBytes) {
559             mAttributionReport.mAggregatableFilteringIdMaxBytes = aggregatableFilteringIdMaxBytes;
560             return this;
561         }
562 
563         /**
564          * Given a {@link Trigger} trigger, source registration time, reporting delay, and the api
565          * version, initialize an {@link AggregateReport.Builder} builder that builds a null
566          * aggregate report. A null aggregate report is used to obscure the number of real aggregate
567          * reports.
568          *
569          * @param trigger the trigger
570          * @param fakeSourceTime a fake source registration time
571          * @param delay amount of delay in ms to wait before sending out report. Only applicable if
572          *     the trigger's trigger context id is null
573          * @param apiVersion api version string that is sent to aggregate service
574          * @return builder initialized to build a null aggregate report
575          * @throws JSONException thrown if fake contributions create invalid JSON. Fake
576          *     contributions are hardcoded, so this should not be thrown.
577          */
getNullAggregateReportBuilder( Trigger trigger, @Nullable Long fakeSourceTime, long delay, String apiVersion, String api, Flags flags)578         public Builder getNullAggregateReportBuilder(
579                 Trigger trigger,
580                 @Nullable Long fakeSourceTime,
581                 long delay,
582                 String apiVersion,
583                 String api,
584                 Flags flags)
585                 throws JSONException {
586             mAttributionReport.mId = UUID.randomUUID().toString();
587             long reportTime = trigger.getTriggerTime();
588             if (isDelayed(trigger, flags)) {
589                 reportTime += delay;
590             }
591 
592             AggregateHistogramContribution.Builder paddingContributionBuilder =
593                     new AggregateHistogramContribution.Builder();
594             if (apiVersion.equals(POST_FLEXIBLE_CONTRIBUTION_FILTERING_API_VERSION)) {
595                 paddingContributionBuilder.setPaddingContributionWithFilteringId();
596             } else {
597                 paddingContributionBuilder.setPaddingContribution();
598             }
599 
600             String debugPayload =
601                     AggregateReport.generateDebugPayload(
602                             List.of(paddingContributionBuilder.build()));
603 
604             mAttributionReport.mApiVersion = apiVersion;
605             mAttributionReport.mPublisher = Uri.EMPTY;
606             mAttributionReport.mRegistrationOrigin = trigger.getRegistrationOrigin();
607             mAttributionReport.mAttributionDestination = trigger.getAttributionDestinationBaseUri();
608             mAttributionReport.mSourceRegistrationTime = fakeSourceTime;
609             mAttributionReport.mScheduledReportTime = reportTime;
610             mAttributionReport.mDebugCleartextPayload = debugPayload;
611             mAttributionReport.mSourceDebugKey = null;
612             mAttributionReport.mIsFakeReport = true;
613             mAttributionReport.mTriggerId = trigger.getId();
614             mAttributionReport.mTriggerContextId = trigger.getTriggerContextId();
615             mAttributionReport.mTriggerTime = trigger.getTriggerTime();
616             mAttributionReport.mApi = api;
617             mAttributionReport.mAggregatableFilteringIdMaxBytes =
618                     trigger.getAggregatableFilteringIdMaxBytes();
619 
620             if (trigger.getAggregationCoordinatorOrigin() != null) {
621                 mAttributionReport.mAggregationCoordinatorOrigin =
622                         trigger.getAggregationCoordinatorOrigin();
623             } else {
624                 mAttributionReport.mAggregationCoordinatorOrigin =
625                         Uri.parse(
626                                 AdServicesConfig
627                                         .getMeasurementDefaultAggregationCoordinatorOrigin());
628             }
629 
630             if (flags.getMeasurementEnableBothSideDebugKeysInReports()) {
631                 mAttributionReport.mTriggerDebugKey = null;
632             } else if ((trigger.getDestinationType() == EventSurfaceType.APP
633                             && trigger.hasAdIdPermission())
634                     || (trigger.getDestinationType() == EventSurfaceType.WEB
635                             && trigger.hasArDebugPermission())) {
636                 mAttributionReport.mTriggerDebugKey = trigger.getDebugKey();
637             }
638 
639             return this;
640         }
641 
642         /** Build the {@link AggregateReport}. */
build()643         public AggregateReport build() {
644             return mAttributionReport;
645         }
646     }
647 }
648