• 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.net.Uri;
22 import android.util.Pair;
23 
24 import androidx.annotation.Nullable;
25 
26 import com.android.adservices.service.measurement.noising.SourceNoiseHandler;
27 import com.android.adservices.service.measurement.reporting.EventReportWindowCalcDelegate;
28 import com.android.adservices.service.measurement.util.Debug;
29 import com.android.adservices.service.measurement.util.UnsignedLong;
30 
31 import com.google.common.collect.ImmutableMultiset;
32 
33 import java.lang.annotation.Retention;
34 import java.lang.annotation.RetentionPolicy;
35 import java.util.List;
36 import java.util.Objects;
37 
38 /**
39  * POJO for EventReport.
40  */
41 public class EventReport {
42 
43     private String mId;
44     private UnsignedLong mSourceEventId;
45     private long mReportTime;
46     private long mTriggerTime;
47     private long mTriggerPriority;
48     private List<Uri> mAttributionDestinations;
49     private String mEnrollmentId;
50     private UnsignedLong mTriggerData;
51     private UnsignedLong mTriggerDedupKey;
52     private double mRandomizedTriggerRate;
53     private @Status int mStatus;
54     private @DebugReportStatus int mDebugReportStatus;
55     private Source.SourceType mSourceType;
56     @Nullable private UnsignedLong mSourceDebugKey;
57     @Nullable private UnsignedLong mTriggerDebugKey;
58     private String mSourceId;
59     private String mTriggerId;
60     private Uri mRegistrationOrigin;
61 
62     @IntDef(value = {Status.PENDING, Status.DELIVERED, Status.MARKED_TO_DELETE})
63     @Retention(RetentionPolicy.SOURCE)
64     public @interface Status {
65         int PENDING = 0;
66         int DELIVERED = 1;
67         int MARKED_TO_DELETE = 2;
68     }
69 
70     @IntDef(
71             value = {
72                 DebugReportStatus.NONE,
73                 DebugReportStatus.PENDING,
74                 DebugReportStatus.DELIVERED,
75             })
76     @Retention(RetentionPolicy.SOURCE)
77     public @interface DebugReportStatus {
78         int NONE = 0;
79         int PENDING = 1;
80         int DELIVERED = 2;
81     }
82 
EventReport()83     private EventReport() {
84         mTriggerDedupKey = null;
85     }
86 
87     @Override
equals(Object obj)88     public boolean equals(Object obj) {
89         if (!(obj instanceof EventReport)) {
90             return false;
91         }
92         EventReport eventReport = (EventReport) obj;
93         return mStatus == eventReport.mStatus
94                 && mDebugReportStatus == eventReport.mDebugReportStatus
95                 && mReportTime == eventReport.mReportTime
96                 && Objects.equals(mAttributionDestinations, eventReport.mAttributionDestinations)
97                 && ImmutableMultiset.copyOf(mAttributionDestinations)
98                         .equals(ImmutableMultiset.copyOf(eventReport.mAttributionDestinations))
99                 && Objects.equals(mEnrollmentId, eventReport.mEnrollmentId)
100                 && mTriggerTime == eventReport.mTriggerTime
101                 && Objects.equals(mTriggerData, eventReport.mTriggerData)
102                 && Objects.equals(mSourceEventId, eventReport.mSourceEventId)
103                 && mTriggerPriority == eventReport.mTriggerPriority
104                 && Objects.equals(mTriggerDedupKey, eventReport.mTriggerDedupKey)
105                 && mSourceType == eventReport.mSourceType
106                 && mRandomizedTriggerRate == eventReport.mRandomizedTriggerRate
107                 && Objects.equals(mSourceDebugKey, eventReport.mSourceDebugKey)
108                 && Objects.equals(mTriggerDebugKey, eventReport.mTriggerDebugKey)
109                 && Objects.equals(mSourceId, eventReport.mSourceId)
110                 && Objects.equals(mTriggerId, eventReport.mTriggerId)
111                 && Objects.equals(mRegistrationOrigin, eventReport.mRegistrationOrigin);
112     }
113 
114     @Override
hashCode()115     public int hashCode() {
116         return Objects.hash(
117                 mStatus,
118                 mDebugReportStatus,
119                 mReportTime,
120                 mAttributionDestinations,
121                 mEnrollmentId,
122                 mTriggerTime,
123                 mTriggerData,
124                 mSourceEventId,
125                 mTriggerPriority,
126                 mTriggerDedupKey,
127                 mSourceType,
128                 mRandomizedTriggerRate,
129                 mSourceDebugKey,
130                 mTriggerDebugKey,
131                 mSourceId,
132                 mTriggerId,
133                 mRegistrationOrigin);
134     }
135 
136     /** Unique identifier for the report. */
getId()137     public String getId() {
138         return mId;
139     }
140 
141     /** Identifier of the associated {@link Source} event. */
getSourceEventId()142     public UnsignedLong getSourceEventId() {
143         return mSourceEventId;
144     }
145 
146     /**
147      * Scheduled time for the report to be sent.
148      */
getReportTime()149     public long getReportTime() {
150         return mReportTime;
151     }
152 
153     /**
154      * TriggerTime of the associated {@link Trigger}.
155      */
getTriggerTime()156     public long getTriggerTime() {
157         return mTriggerTime;
158     }
159 
160     /**
161      * Priority of the associated {@link Trigger}.
162      */
getTriggerPriority()163     public long getTriggerPriority() {
164         return mTriggerPriority;
165     }
166 
167     /**
168      * AttributionDestinations of the {@link Source} and {@link Trigger}.
169      */
getAttributionDestinations()170     public List<Uri> getAttributionDestinations() {
171         return mAttributionDestinations;
172     }
173 
174     /**
175      * Ad Tech enrollment ID.
176      */
getEnrollmentId()177     public String getEnrollmentId() {
178         return mEnrollmentId;
179     }
180 
181     /**
182      * Metadata for the report.
183      */
getTriggerData()184     public UnsignedLong getTriggerData() {
185         return mTriggerData;
186     }
187 
188     /**
189      * Deduplication key of the associated {@link Trigger}
190      */
getTriggerDedupKey()191     public UnsignedLong getTriggerDedupKey() {
192         return mTriggerDedupKey;
193     }
194 
195     /**
196      * Current {@link Status} of the report.
197      */
getStatus()198     public @Status int getStatus() {
199         return mStatus;
200     }
201 
202     /** Current {@link DebugReportStatus} of the report. */
getDebugReportStatus()203     public @DebugReportStatus int getDebugReportStatus() {
204         return mDebugReportStatus;
205     }
206 
207     /**
208      * SourceType of the event's source.
209      */
getSourceType()210     public Source.SourceType getSourceType() {
211         return mSourceType;
212     }
213 
214     /**
215      * Randomized trigger rate for noising
216      */
getRandomizedTriggerRate()217     public double getRandomizedTriggerRate() {
218         return mRandomizedTriggerRate;
219     }
220 
221     /** Source Debug Key */
222     @Nullable
getSourceDebugKey()223     public UnsignedLong getSourceDebugKey() {
224         return mSourceDebugKey;
225     }
226 
227     /** Trigger Debug Key */
228     @Nullable
getTriggerDebugKey()229     public UnsignedLong getTriggerDebugKey() {
230         return mTriggerDebugKey;
231     }
232 
233     /** Source ID */
getSourceId()234     public String getSourceId() {
235         return mSourceId;
236     }
237 
238     /** Trigger ID */
getTriggerId()239     public String getTriggerId() {
240         return mTriggerId;
241     }
242 
243     /** Returns registration origin used to register the source and trigger */
getRegistrationOrigin()244     public Uri getRegistrationOrigin() {
245         return mRegistrationOrigin;
246     }
247 
248     /** Builder for {@link EventReport} */
249     public static final class Builder {
250 
251         private final EventReport mBuilding;
252 
Builder()253         public Builder() {
254             mBuilding = new EventReport();
255         }
256 
257         /**
258          * See {@link EventReport#getId()}
259          */
setId(String id)260         public Builder setId(String id) {
261             mBuilding.mId = id;
262             return this;
263         }
264 
265         /** See {@link EventReport#getSourceEventId()} */
setSourceEventId(UnsignedLong sourceEventId)266         public Builder setSourceEventId(UnsignedLong sourceEventId) {
267             mBuilding.mSourceEventId = sourceEventId;
268             return this;
269         }
270 
271         /** See {@link EventReport#getEnrollmentId()} */
setEnrollmentId(String enrollmentId)272         public Builder setEnrollmentId(String enrollmentId) {
273             mBuilding.mEnrollmentId = enrollmentId;
274             return this;
275         }
276 
277         /**
278          * See {@link EventReport#getAttributionDestination()}
279          */
setAttributionDestinations(List<Uri> attributionDestinations)280         public Builder setAttributionDestinations(List<Uri> attributionDestinations) {
281             mBuilding.mAttributionDestinations = attributionDestinations;
282             return this;
283         }
284 
285         /**
286          * See {@link EventReport#getTriggerTime()}
287          */
setTriggerTime(long triggerTime)288         public Builder setTriggerTime(long triggerTime) {
289             mBuilding.mTriggerTime = triggerTime;
290             return this;
291         }
292 
293         /**
294          * See {@link EventReport#getTriggerData()}
295          */
setTriggerData(UnsignedLong triggerData)296         public Builder setTriggerData(UnsignedLong triggerData) {
297             mBuilding.mTriggerData = triggerData;
298             return this;
299         }
300 
301         /**
302          * See {@link EventReport#getTriggerPriority()}
303          */
setTriggerPriority(long triggerPriority)304         public Builder setTriggerPriority(long triggerPriority) {
305             mBuilding.mTriggerPriority = triggerPriority;
306             return this;
307         }
308 
309         /**
310          * See {@link EventReport#getTriggerDedupKey()}
311          */
setTriggerDedupKey(UnsignedLong triggerDedupKey)312         public Builder setTriggerDedupKey(UnsignedLong triggerDedupKey) {
313             mBuilding.mTriggerDedupKey = triggerDedupKey;
314             return this;
315         }
316 
317         /**
318          * See {@link EventReport#getReportTime()}
319          */
setReportTime(long reportTime)320         public Builder setReportTime(long reportTime) {
321             mBuilding.mReportTime = reportTime;
322             return this;
323         }
324 
325         /**
326          * See {@link EventReport#getStatus()}
327          */
setStatus(@tatus int status)328         public Builder setStatus(@Status int status) {
329             mBuilding.mStatus = status;
330             return this;
331         }
332 
333         /** See {@link EventReport#getDebugReportStatus()}} */
setDebugReportStatus(@ebugReportStatus int debugReportStatus)334         public Builder setDebugReportStatus(@DebugReportStatus int debugReportStatus) {
335             mBuilding.mDebugReportStatus = debugReportStatus;
336             return this;
337         }
338 
339         /**
340          * See {@link EventReport#getSourceType()}
341          */
setSourceType(Source.SourceType sourceType)342         public Builder setSourceType(Source.SourceType sourceType) {
343             mBuilding.mSourceType = sourceType;
344             return this;
345         }
346 
347         /** See {@link EventReport#getRandomizedTriggerRate()}} */
setRandomizedTriggerRate(double randomizedTriggerRate)348         public Builder setRandomizedTriggerRate(double randomizedTriggerRate) {
349             mBuilding.mRandomizedTriggerRate = randomizedTriggerRate;
350             return this;
351         }
352 
353         /** See {@link EventReport#getSourceDebugKey()}} */
setSourceDebugKey(UnsignedLong sourceDebugKey)354         public Builder setSourceDebugKey(UnsignedLong sourceDebugKey) {
355             mBuilding.mSourceDebugKey = sourceDebugKey;
356             return this;
357         }
358 
359         /** See {@link EventReport#getTriggerDebugKey()}} */
setTriggerDebugKey(UnsignedLong triggerDebugKey)360         public Builder setTriggerDebugKey(UnsignedLong triggerDebugKey) {
361             mBuilding.mTriggerDebugKey = triggerDebugKey;
362             return this;
363         }
364 
365         /** See {@link EventReport#getSourceId()} */
setSourceId(String sourceId)366         public Builder setSourceId(String sourceId) {
367             mBuilding.mSourceId = sourceId;
368             return this;
369         }
370 
371         /** See {@link EventReport#getTriggerId()} */
setTriggerId(String triggerId)372         public Builder setTriggerId(String triggerId) {
373             mBuilding.mTriggerId = triggerId;
374             return this;
375         }
376 
377         /** See {@link Source#getRegistrationOrigin()} ()} */
378         @NonNull
setRegistrationOrigin(Uri registrationOrigin)379         public Builder setRegistrationOrigin(Uri registrationOrigin) {
380             mBuilding.mRegistrationOrigin = registrationOrigin;
381             return this;
382         }
383 
384         // TODO (b/285607306): cleanup since this doesn't just do "populateFromSourceAndTrigger"
385         /** Populates fields using {@link Source}, {@link Trigger} and {@link EventTrigger}. */
populateFromSourceAndTrigger( @onNull Source source, @NonNull Trigger trigger, @NonNull EventTrigger eventTrigger, @Nullable Pair<UnsignedLong, UnsignedLong> debugKeyPair, @NonNull EventReportWindowCalcDelegate eventReportWindowCalcDelegate, @NonNull SourceNoiseHandler sourceNoiseHandler, List<Uri> eventReportDestinations)386         public Builder populateFromSourceAndTrigger(
387                 @NonNull Source source,
388                 @NonNull Trigger trigger,
389                 @NonNull EventTrigger eventTrigger,
390                 @Nullable Pair<UnsignedLong, UnsignedLong> debugKeyPair,
391                 @NonNull EventReportWindowCalcDelegate eventReportWindowCalcDelegate,
392                 @NonNull SourceNoiseHandler sourceNoiseHandler,
393                 List<Uri> eventReportDestinations) {
394             mBuilding.mTriggerPriority = eventTrigger.getTriggerPriority();
395             mBuilding.mTriggerDedupKey = eventTrigger.getDedupKey();
396             // truncate trigger data to 3-bit or 1-bit based on {@link Source.SourceType}
397             mBuilding.mTriggerData = getTruncatedTriggerData(source, eventTrigger);
398             mBuilding.mTriggerTime = trigger.getTriggerTime();
399             mBuilding.mSourceEventId = source.getEventId();
400             mBuilding.mEnrollmentId = source.getEnrollmentId();
401             mBuilding.mStatus = Status.PENDING;
402             mBuilding.mAttributionDestinations = eventReportDestinations;
403             mBuilding.mReportTime =
404                     eventReportWindowCalcDelegate.getReportingTime(
405                             source, trigger.getTriggerTime(), trigger.getDestinationType());
406             mBuilding.mSourceType = source.getSourceType();
407             mBuilding.mRandomizedTriggerRate =
408                     sourceNoiseHandler.getRandomAttributionProbability(source);
409             mBuilding.mSourceDebugKey = debugKeyPair.first;
410             mBuilding.mTriggerDebugKey = debugKeyPair.second;
411             mBuilding.mDebugReportStatus = DebugReportStatus.NONE;
412             if (Debug.isAttributionDebugReportPermitted(source, trigger,
413                     mBuilding.mSourceDebugKey, mBuilding.mTriggerDebugKey)) {
414                 mBuilding.mDebugReportStatus = DebugReportStatus.PENDING;
415             }
416             mBuilding.mSourceId = source.getId();
417             mBuilding.mTriggerId = trigger.getId();
418             mBuilding.mRegistrationOrigin = trigger.getRegistrationOrigin();
419             return this;
420         }
421 
getTruncatedTriggerData(Source source, EventTrigger eventTrigger)422         private UnsignedLong getTruncatedTriggerData(Source source, EventTrigger eventTrigger) {
423             UnsignedLong triggerData = eventTrigger.getTriggerData();
424             return triggerData.mod(source.getTriggerDataCardinality());
425         }
426 
427         /**
428          * Build the {@link EventReport}.
429          */
build()430         public EventReport build() {
431             return mBuilding;
432         }
433     }
434 }
435