Parse aggregate related fields from header during registration.
Test: atest -c com.android.adservices.service.measurement.registration.SourceRegistrationTest
Test: atest -c com.android.adservices.service.measurement.registration.TriggerRegistrationTest
Test: atest -c com.android.adservices.service.measurement.registration.SourceFetcherTest
Test: atest -c com.android.adservices.service.measurement.registration.TriggerFetcherTest
Test: atest -c com.android.adservices.data.measurement.MeasurementDaoTest
Change-Id: I12bd214d1a875a1eed2ee4462f451c30be669937
diff --git a/adservices/service-core/java/com/android/adservices/data/measurement/IMeasurementDao.java b/adservices/service-core/java/com/android/adservices/data/measurement/IMeasurementDao.java
index 0bb3734..a5046e4 100644
--- a/adservices/service-core/java/com/android/adservices/data/measurement/IMeasurementDao.java
+++ b/adservices/service-core/java/com/android/adservices/data/measurement/IMeasurementDao.java
@@ -16,10 +16,10 @@
package com.android.adservices.data.measurement;
-import android.annotation.Nullable;
import android.net.Uri;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import com.android.adservices.service.measurement.AdtechUrl;
import com.android.adservices.service.measurement.EventReport;
@@ -43,7 +43,8 @@
*/
void insertTrigger(@NonNull Uri attributionDestination, @NonNull Uri reportTo,
@NonNull Uri registrant, @NonNull Long triggerTime, @NonNull Long triggerData,
- @Nullable Long dedupKey, @NonNull Long priority) throws DatastoreException;
+ @Nullable Long dedupKey, @NonNull Long priority, @Nullable String aggregateTriggerData,
+ @Nullable String aggregateValues) throws DatastoreException;
/**
* Returns list of ids for all pending {@link Trigger}.
@@ -79,8 +80,9 @@
void insertSource(@NonNull Long sourceEventId, @NonNull Uri attributionSource,
@NonNull Uri attributionDestination, @NonNull Uri reportTo, @NonNull Uri registrant,
@NonNull Long sourceEventTime, @NonNull Long expiryTime, @NonNull Long priority,
- @NonNull Source.SourceType sourceType,
- @Source.AttributionMode int attributionMode) throws DatastoreException;
+ @NonNull Source.SourceType sourceType, @Source.AttributionMode int attributionMode,
+ @Nullable String aggregateSource,
+ @Nullable String aggregateFilterData) throws DatastoreException;
/**
* Queries and returns the list of matching {@link Source} for the provided {@link Trigger}.
diff --git a/adservices/service-core/java/com/android/adservices/data/measurement/MeasurementDao.java b/adservices/service-core/java/com/android/adservices/data/measurement/MeasurementDao.java
index 9fb215c..88650b0 100644
--- a/adservices/service-core/java/com/android/adservices/data/measurement/MeasurementDao.java
+++ b/adservices/service-core/java/com/android/adservices/data/measurement/MeasurementDao.java
@@ -18,7 +18,6 @@
import static com.android.adservices.service.AdServicesConfig.MEASUREMENT_DELETE_EXPIRED_WINDOW_MS;
-import android.annotation.Nullable;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.DatabaseUtils;
@@ -27,6 +26,7 @@
import android.net.Uri;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import com.android.adservices.LogUtil;
import com.android.adservices.service.measurement.AdtechUrl;
@@ -63,7 +63,8 @@
@Override
public void insertTrigger(@NonNull Uri attributionDestination, @NonNull Uri reportTo,
@NonNull Uri registrant, @NonNull Long triggerTime, @NonNull Long triggerData,
- @Nullable Long dedupKey, @NonNull Long priority) throws DatastoreException {
+ @Nullable Long dedupKey, @NonNull Long priority, @Nullable String aggregateTriggerData,
+ @Nullable String aggregateValues) throws DatastoreException {
validateNonNull(attributionDestination, reportTo, registrant, triggerTime, triggerData,
priority);
validateUri(attributionDestination, reportTo, registrant);
@@ -79,6 +80,8 @@
values.put(MeasurementTables.TriggerContract.STATUS, Trigger.Status.PENDING);
values.put(MeasurementTables.TriggerContract.REPORT_TO, reportTo.toString());
values.put(MeasurementTables.TriggerContract.REGISTRANT, registrant.toString());
+ values.put(MeasurementTables.TriggerContract.AGGREGATE_TRIGGER_DATA, aggregateTriggerData);
+ values.put(MeasurementTables.TriggerContract.AGGREGATE_VALUES, aggregateValues);
long rowId = mSQLTransaction.getDatabase()
.insert(MeasurementTables.TriggerContract.TABLE,
/*nullColumnHack=*/null, values);
@@ -145,8 +148,9 @@
public void insertSource(@NonNull Long sourceEventId, @NonNull Uri attributionSource,
@NonNull Uri attributionDestination, @NonNull Uri reportTo, @NonNull Uri registrant,
@NonNull Long sourceEventTime, @NonNull Long expiryTime, @NonNull Long priority,
- @NonNull Source.SourceType sourceType,
- @Source.AttributionMode int attributionMode) throws DatastoreException {
+ @NonNull Source.SourceType sourceType, @Source.AttributionMode int attributionMode,
+ @Nullable String aggregateSource, @Nullable String aggregateFilterData)
+ throws DatastoreException {
validateNonNull(sourceEventId, attributionSource, attributionDestination, reportTo,
registrant, sourceEventTime, expiryTime, priority, sourceType);
validateUri(attributionSource, attributionDestination, reportTo, registrant);
@@ -166,6 +170,8 @@
values.put(MeasurementTables.SourceContract.SOURCE_TYPE, sourceType.name());
values.put(MeasurementTables.SourceContract.REGISTRANT, registrant.toString());
values.put(MeasurementTables.SourceContract.ATTRIBUTION_MODE, attributionMode);
+ values.put(MeasurementTables.SourceContract.AGGREGATE_SOURCE, aggregateSource);
+ values.put(MeasurementTables.SourceContract.FILTER_DATA, aggregateFilterData);
long rowId = mSQLTransaction.getDatabase()
.insert(MeasurementTables.SourceContract.TABLE,
/*nullColumnHack=*/null, values);
diff --git a/adservices/service-core/java/com/android/adservices/service/measurement/MeasurementImpl.java b/adservices/service-core/java/com/android/adservices/service/measurement/MeasurementImpl.java
index 0be416f..8734d34 100644
--- a/adservices/service-core/java/com/android/adservices/service/measurement/MeasurementImpl.java
+++ b/adservices/service-core/java/com/android/adservices/service/measurement/MeasurementImpl.java
@@ -183,6 +183,8 @@
// Setting as TRUTHFULLY as default value for tests.
// This will be overwritten by getSourceEventReports.
.setAttributionMode(Source.AttributionMode.TRUTHFULLY)
+ .setAggregateSource(registration.getAggregateSource())
+ .setAggregateFilterData(registration.getAggregateFilterData())
.build();
List<EventReport> eventReports = getSourceEventReports(source);
mDatastoreManager.runInTransaction((dao) -> {
@@ -196,7 +198,9 @@
/* expiryTime */ source.getExpiryTime(),
/* priority */ source.getPriority(),
/* sourceType */ source.getSourceType(),
- /* attributionMode */ source.getAttributionMode());
+ /* attributionMode */ source.getAttributionMode(),
+ /* aggregateSource */ source.getAggregateSource(),
+ /* aggregateFilterData */ source.getAggregateFilterData());
for (EventReport report : eventReports) {
dao.insertEventReport(report);
}
@@ -241,7 +245,9 @@
/* triggerTime */ triggerTime,
/* triggerData */ registration.getTriggerData(),
/* dedupKey */ registration.getDeduplicationKey(),
- /* priority */ registration.getTriggerPriority()));
+ /* priority */ registration.getTriggerPriority(),
+ /* aggregateTriggerData */ registration.getAggregateTriggerData(),
+ /* aggregateValues */ registration.getAggregateValues()));
}
try (ContentProviderClient contentProviderClient =
mContentResolver.acquireContentProviderClient(TRIGGER_URI)) {
diff --git a/adservices/service-core/java/com/android/adservices/service/measurement/registration/SourceFetcher.java b/adservices/service-core/java/com/android/adservices/service/measurement/registration/SourceFetcher.java
index 6a69dca..074959a 100644
--- a/adservices/service-core/java/com/android/adservices/service/measurement/registration/SourceFetcher.java
+++ b/adservices/service-core/java/com/android/adservices/service/measurement/registration/SourceFetcher.java
@@ -71,6 +71,10 @@
if (json.has(EventSourceContract.PRIORITY) && !json.isNull(EventSourceContract.PRIORITY)) {
result.setSourcePriority(json.getLong(EventSourceContract.PRIORITY));
}
+ // This "filter_data" field is used to generate aggregate report.
+ if (json.has("filter_data") && !json.isNull("filter_data")) {
+ result.setAggregateFilterData(json.getJSONObject("filter_data").toString());
+ }
}
private static void setExpiry(long expiry, SourceRegistration.Builder result) {
@@ -113,8 +117,9 @@
LogUtil.d("Expected one aggregate source!");
return false;
}
- // TODO: Handle aggregates. additionalResult will be false until then.
- additionalResult = false;
+ // Parse in aggregate source. additionalResult will be false until then.
+ result.setAggregateSource(field.get(0));
+ additionalResult = true;
}
if (additionalResult) {
addToResults.add(result.build());
diff --git a/adservices/service-core/java/com/android/adservices/service/measurement/registration/SourceRegistration.java b/adservices/service-core/java/com/android/adservices/service/measurement/registration/SourceRegistration.java
index 31b9480..ee0f717 100644
--- a/adservices/service-core/java/com/android/adservices/service/measurement/registration/SourceRegistration.java
+++ b/adservices/service-core/java/com/android/adservices/service/measurement/registration/SourceRegistration.java
@@ -31,6 +31,8 @@
private final long mSourceEventId;
private final long mExpiry;
private final long mSourcePriority;
+ private final String mAggregateSource;
+ private final String mAggregateFilterData;
/**
* Create a new source registration.
@@ -41,13 +43,17 @@
@NonNull Uri destination,
long sourceEventId,
long expiry,
- long sourcePriority) {
+ long sourcePriority,
+ String aggregateSource,
+ String aggregateFilterData) {
mTopOrigin = topOrigin;
mReportingOrigin = reportingOrigin;
mDestination = destination;
mSourceEventId = sourceEventId;
mExpiry = expiry;
mSourcePriority = sourcePriority;
+ mAggregateSource = aggregateSource;
+ mAggregateFilterData = aggregateFilterData;
}
/**
@@ -93,6 +99,20 @@
}
/**
+ * Aggregate source used to generate aggregate report.
+ */
+ public String getAggregateSource() {
+ return mAggregateSource;
+ }
+
+ /**
+ * Aggregate filter data used to generate aggregate report.
+ */
+ public String getAggregateFilterData() {
+ return mAggregateFilterData;
+ }
+
+ /**
* A builder for {@link SourceRegistration}.
*/
public static final class Builder {
@@ -102,6 +122,8 @@
private long mSourceEventId;
private long mExpiry;
private long mSourcePriority;
+ private String mAggregateSource;
+ private String mAggregateFilterData;
public Builder() {
mTopOrigin = Uri.EMPTY;
@@ -159,13 +181,29 @@
}
/**
+ * See {@link SourceRegistration#getAggregateSource()}.
+ */
+ public Builder setAggregateSource(String aggregateSource) {
+ mAggregateSource = aggregateSource;
+ return this;
+ }
+
+ /**
+ * See {@link SourceRegistration#getAggregateFilterData()}.
+ */
+ public Builder setAggregateFilterData(String aggregateFilterData) {
+ mAggregateFilterData = aggregateFilterData;
+ return this;
+ }
+
+ /**
* Build the SourceRegistration.
*/
public @NonNull SourceRegistration build() {
if (mTopOrigin == null
|| mReportingOrigin == null
|| mDestination == null) {
- throw new IllegalArgumentException("uinitialized fields");
+ throw new IllegalArgumentException("uninitialized fields");
}
return new SourceRegistration(
mTopOrigin,
@@ -173,7 +211,9 @@
mDestination,
mSourceEventId,
mExpiry,
- mSourcePriority);
+ mSourcePriority,
+ mAggregateSource,
+ mAggregateFilterData);
}
}
}
diff --git a/adservices/service-core/java/com/android/adservices/service/measurement/registration/TriggerFetcher.java b/adservices/service-core/java/com/android/adservices/service/measurement/registration/TriggerFetcher.java
index a1db5f3..d31b222 100644
--- a/adservices/service-core/java/com/android/adservices/service/measurement/registration/TriggerFetcher.java
+++ b/adservices/service-core/java/com/android/adservices/service/measurement/registration/TriggerFetcher.java
@@ -100,8 +100,9 @@
LogUtil.d("Expected one aggregate trigger data!");
return false;
}
- // TODO: Handle aggregates. additionalResult will be false until then.
- additionalResult = false;
+ // Parses in aggregate trigger data. additionalResult will be false until then.
+ result.setAggregateTriggerData(field.get(0));
+ additionalResult = true;
}
field = headers.get("Attribution-Reporting-Register-Aggregatable-Values");
if (field != null) {
@@ -109,8 +110,9 @@
LogUtil.d("Expected one aggregatable values!");
return false;
}
- // TODO: Handle aggregates. additionalResult will be false until then.
- additionalResult = false;
+ // Parses in aggregate values. additionalResult will be false until then.
+ result.setAggregateValues(field.get(0));
+ additionalResult = true;
}
if (additionalResult) {
addToResults.add(result.build());
diff --git a/adservices/service-core/java/com/android/adservices/service/measurement/registration/TriggerRegistration.java b/adservices/service-core/java/com/android/adservices/service/measurement/registration/TriggerRegistration.java
index 09f39d1..5b3f7a0 100644
--- a/adservices/service-core/java/com/android/adservices/service/measurement/registration/TriggerRegistration.java
+++ b/adservices/service-core/java/com/android/adservices/service/measurement/registration/TriggerRegistration.java
@@ -28,6 +28,8 @@
private final long mTriggerData;
private final long mTriggerPriority;
private final Long mDeduplicationKey;
+ private final String mAggregateTriggerData;
+ private final String mAggregateValues;
/**
* Create a trigger registration.
@@ -37,12 +39,16 @@
@NonNull Uri reportingOrigin,
long triggerData,
long triggerPriority,
- Long deduplicationKey) {
+ Long deduplicationKey,
+ String aggregateTriggerData,
+ String aggregateValues) {
mTopOrigin = topOrigin;
mReportingOrigin = reportingOrigin;
mTriggerData = triggerData;
mTriggerPriority = triggerPriority;
mDeduplicationKey = deduplicationKey;
+ mAggregateTriggerData = aggregateTriggerData;
+ mAggregateValues = aggregateValues;
}
/**
@@ -81,6 +87,20 @@
}
/**
+ * Aggregate trigger data is used to generate aggregate report.
+ */
+ public String getAggregateTriggerData() {
+ return mAggregateTriggerData;
+ }
+
+ /**
+ * Aggregate value is used to generate aggregate report.
+ */
+ public String getAggregateValues() {
+ return mAggregateValues;
+ }
+
+ /**
* A builder for {@link TriggerRegistration}.
*/
public static final class Builder {
@@ -89,10 +109,13 @@
private long mTriggerData;
private long mTriggerPriority;
private Long mDeduplicationKey;
+ private String mAggregateTriggerData;
+ private String mAggregateValues;
public Builder() {
mTopOrigin = Uri.EMPTY;
mReportingOrigin = Uri.EMPTY;
+ mDeduplicationKey = null;
}
/**
@@ -136,6 +159,22 @@
}
/**
+ * See {@link TriggerRegistration#getAggregateTriggerData()}.
+ */
+ public Builder setAggregateTriggerData(String aggregateTriggerData) {
+ mAggregateTriggerData = aggregateTriggerData;
+ return this;
+ }
+
+ /**
+ * See {@link TriggerRegistration#getAggregateValues()}.
+ */
+ public Builder setAggregateValues(String aggregateValues) {
+ mAggregateValues = aggregateValues;
+ return this;
+ }
+
+ /**
* Build the TriggerRegistration.
*/
public @NonNull TriggerRegistration build() {
@@ -148,7 +187,9 @@
mReportingOrigin,
mTriggerData,
mTriggerPriority,
- mDeduplicationKey);
+ mDeduplicationKey,
+ mAggregateTriggerData,
+ mAggregateValues);
}
}
}
diff --git a/adservices/tests/unittest/service-core/src/com/android/adservices/data/measurement/MeasurementDaoTest.java b/adservices/tests/unittest/service-core/src/com/android/adservices/data/measurement/MeasurementDaoTest.java
index 34119d1..8332d37 100644
--- a/adservices/tests/unittest/service-core/src/com/android/adservices/data/measurement/MeasurementDaoTest.java
+++ b/adservices/tests/unittest/service-core/src/com/android/adservices/data/measurement/MeasurementDaoTest.java
@@ -26,6 +26,7 @@
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
+import androidx.annotation.Nullable;
import androidx.test.core.app.ApplicationProvider;
import com.android.adservices.data.DbHelper;
@@ -33,6 +34,9 @@
import com.android.adservices.service.measurement.Source;
import com.android.adservices.service.measurement.Trigger;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
import org.junit.After;
import org.junit.Assert;
import org.junit.Test;
@@ -41,6 +45,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
@@ -80,8 +85,9 @@
ValidSourceParams.EXPIRY_TIME,
ValidSourceParams.PRIORITY,
ValidSourceParams.sSourceType,
- ValidSourceParams.sAttributionMode
- )
+ ValidSourceParams.sAttributionMode,
+ ValidSourceParams.buildAggregateSource(),
+ ValidSourceParams.buildAggregateFilterData())
);
try (Cursor sourceCursor =
@@ -117,7 +123,9 @@
ValidSourceParams.EXPIRY_TIME,
ValidSourceParams.PRIORITY,
ValidSourceParams.sSourceType,
- ValidSourceParams.sAttributionMode);
+ ValidSourceParams.sAttributionMode,
+ ValidSourceParams.buildAggregateSource(),
+ ValidSourceParams.buildAggregateFilterData());
}
@Test
@@ -132,7 +140,9 @@
ValidSourceParams.EXPIRY_TIME,
ValidSourceParams.PRIORITY,
ValidSourceParams.sSourceType,
- ValidSourceParams.sAttributionMode);
+ ValidSourceParams.sAttributionMode,
+ ValidSourceParams.buildAggregateSource(),
+ ValidSourceParams.buildAggregateFilterData());
assertInvalidSourceArguments(
ValidSourceParams.SOURCE_EVENT_ID,
@@ -144,7 +154,9 @@
ValidSourceParams.EXPIRY_TIME,
ValidSourceParams.PRIORITY,
ValidSourceParams.sSourceType,
- ValidSourceParams.sAttributionMode);
+ ValidSourceParams.sAttributionMode,
+ ValidSourceParams.buildAggregateSource(),
+ ValidSourceParams.buildAggregateFilterData());
}
@Test
@@ -159,7 +171,9 @@
ValidSourceParams.EXPIRY_TIME,
ValidSourceParams.PRIORITY,
ValidSourceParams.sSourceType,
- ValidSourceParams.sAttributionMode);
+ ValidSourceParams.sAttributionMode,
+ ValidSourceParams.buildAggregateSource(),
+ ValidSourceParams.buildAggregateFilterData());
assertInvalidSourceArguments(
ValidSourceParams.SOURCE_EVENT_ID,
@@ -171,7 +185,9 @@
ValidSourceParams.EXPIRY_TIME,
ValidSourceParams.PRIORITY,
ValidSourceParams.sSourceType,
- ValidSourceParams.sAttributionMode);
+ ValidSourceParams.sAttributionMode,
+ ValidSourceParams.buildAggregateSource(),
+ ValidSourceParams.buildAggregateFilterData());
}
@Test
@@ -186,7 +202,9 @@
ValidSourceParams.EXPIRY_TIME,
ValidSourceParams.PRIORITY,
ValidSourceParams.sSourceType,
- ValidSourceParams.sAttributionMode);
+ ValidSourceParams.sAttributionMode,
+ ValidSourceParams.buildAggregateSource(),
+ ValidSourceParams.buildAggregateFilterData());
assertInvalidSourceArguments(
ValidSourceParams.SOURCE_EVENT_ID,
@@ -198,7 +216,9 @@
ValidSourceParams.EXPIRY_TIME,
ValidSourceParams.PRIORITY,
ValidSourceParams.sSourceType,
- ValidSourceParams.sAttributionMode);
+ ValidSourceParams.sAttributionMode,
+ ValidSourceParams.buildAggregateSource(),
+ ValidSourceParams.buildAggregateFilterData());
}
@Test
@@ -213,7 +233,9 @@
ValidSourceParams.EXPIRY_TIME,
ValidSourceParams.PRIORITY,
ValidSourceParams.sSourceType,
- ValidSourceParams.sAttributionMode);
+ ValidSourceParams.sAttributionMode,
+ ValidSourceParams.buildAggregateSource(),
+ ValidSourceParams.buildAggregateFilterData());
assertInvalidSourceArguments(
ValidSourceParams.SOURCE_EVENT_ID,
@@ -225,7 +247,9 @@
ValidSourceParams.EXPIRY_TIME,
ValidSourceParams.PRIORITY,
ValidSourceParams.sSourceType,
- ValidSourceParams.sAttributionMode);
+ ValidSourceParams.sAttributionMode,
+ ValidSourceParams.buildAggregateSource(),
+ ValidSourceParams.buildAggregateFilterData());
}
@Test
@@ -240,7 +264,9 @@
ValidSourceParams.EXPIRY_TIME,
ValidSourceParams.PRIORITY,
ValidSourceParams.sSourceType,
- ValidSourceParams.sAttributionMode);
+ ValidSourceParams.sAttributionMode,
+ ValidSourceParams.buildAggregateSource(),
+ ValidSourceParams.buildAggregateFilterData());
}
@Test
@@ -255,7 +281,9 @@
null,
ValidSourceParams.PRIORITY,
ValidSourceParams.sSourceType,
- ValidSourceParams.sAttributionMode);
+ ValidSourceParams.sAttributionMode,
+ ValidSourceParams.buildAggregateSource(),
+ ValidSourceParams.buildAggregateFilterData());
}
@Test
@@ -270,7 +298,9 @@
ValidSourceParams.EXPIRY_TIME,
null,
ValidSourceParams.sSourceType,
- ValidSourceParams.sAttributionMode);
+ ValidSourceParams.sAttributionMode,
+ ValidSourceParams.buildAggregateSource(),
+ ValidSourceParams.buildAggregateFilterData());
}
@Test
@@ -285,14 +315,16 @@
ValidSourceParams.EXPIRY_TIME,
ValidSourceParams.PRIORITY,
null,
- ValidSourceParams.sAttributionMode
- );
+ ValidSourceParams.sAttributionMode,
+ ValidSourceParams.buildAggregateSource(),
+ ValidSourceParams.buildAggregateFilterData());
}
private void assertInvalidSourceArguments(Long sourceEventId, Uri attributionSource,
Uri attributionDestination, Uri reportTo, Uri registrant, Long sourceEventTime,
Long expiryTime, Long priority, Source.SourceType sourceType,
- @Source.AttributionMode int attributionMode) {
+ @Source.AttributionMode int attributionMode, @Nullable String aggregateSource,
+ @Nullable String aggregateFilterData) {
DatastoreManagerFactory.getDatastoreManager(sContext).runInTransaction((dao) -> {
try {
dao.insertSource(
@@ -305,8 +337,9 @@
expiryTime,
priority,
sourceType,
- attributionMode
- );
+ attributionMode,
+ aggregateSource,
+ aggregateFilterData);
fail();
} catch (DatastoreException e) {
// Valid Exception
@@ -326,7 +359,9 @@
ValidTriggerParams.TRIGGER_TIME,
ValidTriggerParams.TRIGGER_DATA,
ValidTriggerParams.DEDUP_KEY,
- ValidTriggerParams.PRIORITY
+ ValidTriggerParams.PRIORITY,
+ ValidTriggerParams.buildAggregateTriggerData(),
+ ValidTriggerParams.buildAggregateValues()
)
);
@@ -359,7 +394,9 @@
ValidTriggerParams.TRIGGER_TIME,
ValidTriggerParams.TRIGGER_DATA,
ValidTriggerParams.DEDUP_KEY,
- ValidTriggerParams.PRIORITY);
+ ValidTriggerParams.PRIORITY,
+ ValidTriggerParams.buildAggregateTriggerData(),
+ ValidTriggerParams.buildAggregateValues());
assertInvalidTriggerArguments(
Uri.parse("com.destination"),
@@ -368,7 +405,9 @@
ValidTriggerParams.TRIGGER_TIME,
ValidTriggerParams.TRIGGER_DATA,
ValidTriggerParams.DEDUP_KEY,
- ValidTriggerParams.PRIORITY);
+ ValidTriggerParams.PRIORITY,
+ ValidTriggerParams.buildAggregateTriggerData(),
+ ValidTriggerParams.buildAggregateValues());
}
@Test
@@ -380,7 +419,9 @@
ValidTriggerParams.TRIGGER_TIME,
ValidTriggerParams.TRIGGER_DATA,
ValidTriggerParams.DEDUP_KEY,
- ValidTriggerParams.PRIORITY);
+ ValidTriggerParams.PRIORITY,
+ ValidTriggerParams.buildAggregateTriggerData(),
+ ValidTriggerParams.buildAggregateValues());
assertInvalidTriggerArguments(
ValidTriggerParams.sAttributionDestination,
@@ -389,7 +430,9 @@
ValidTriggerParams.TRIGGER_TIME,
ValidTriggerParams.TRIGGER_DATA,
ValidTriggerParams.DEDUP_KEY,
- ValidTriggerParams.PRIORITY);
+ ValidTriggerParams.PRIORITY,
+ ValidTriggerParams.buildAggregateTriggerData(),
+ ValidTriggerParams.buildAggregateValues());
}
@Test
@@ -401,7 +444,9 @@
ValidTriggerParams.TRIGGER_TIME,
ValidTriggerParams.TRIGGER_DATA,
ValidTriggerParams.DEDUP_KEY,
- ValidTriggerParams.PRIORITY);
+ ValidTriggerParams.PRIORITY,
+ ValidTriggerParams.buildAggregateTriggerData(),
+ ValidTriggerParams.buildAggregateValues());
assertInvalidTriggerArguments(
ValidTriggerParams.sAttributionDestination,
@@ -410,7 +455,9 @@
ValidTriggerParams.TRIGGER_TIME,
ValidTriggerParams.TRIGGER_DATA,
ValidTriggerParams.DEDUP_KEY,
- ValidTriggerParams.PRIORITY);
+ ValidTriggerParams.PRIORITY,
+ ValidTriggerParams.buildAggregateTriggerData(),
+ ValidTriggerParams.buildAggregateValues());
}
@Test
@@ -422,7 +469,9 @@
null,
ValidTriggerParams.TRIGGER_DATA,
ValidTriggerParams.DEDUP_KEY,
- ValidTriggerParams.PRIORITY);
+ ValidTriggerParams.PRIORITY,
+ ValidTriggerParams.buildAggregateTriggerData(),
+ ValidTriggerParams.buildAggregateValues());
}
@Test
@@ -434,7 +483,9 @@
ValidTriggerParams.TRIGGER_TIME,
null,
ValidTriggerParams.DEDUP_KEY,
- ValidTriggerParams.PRIORITY);
+ ValidTriggerParams.PRIORITY,
+ ValidTriggerParams.buildAggregateTriggerData(),
+ ValidTriggerParams.buildAggregateValues());
}
@Test
@@ -449,7 +500,9 @@
ValidTriggerParams.TRIGGER_TIME,
ValidTriggerParams.TRIGGER_DATA,
null,
- ValidTriggerParams.PRIORITY
+ ValidTriggerParams.PRIORITY,
+ ValidTriggerParams.buildAggregateTriggerData(),
+ ValidTriggerParams.buildAggregateValues()
)
);
@@ -482,11 +535,14 @@
ValidTriggerParams.TRIGGER_TIME,
ValidTriggerParams.TRIGGER_DATA,
ValidTriggerParams.DEDUP_KEY,
- null);
+ null,
+ ValidTriggerParams.buildAggregateTriggerData(),
+ ValidTriggerParams.buildAggregateValues());
}
public void assertInvalidTriggerArguments(Uri attributionDestination, Uri reportTo,
- Uri registrant, Long triggerTime, Long triggerData, Long dedupKey, Long priority) {
+ Uri registrant, Long triggerTime, Long triggerData, Long dedupKey, Long priority,
+ @Nullable String aggregateTriggerData, @Nullable String aggregateValues) {
DatastoreManagerFactory.getDatastoreManager(sContext).runInTransaction((dao) -> {
try {
dao.insertTrigger(
@@ -496,7 +552,9 @@
triggerTime,
triggerData,
dedupKey,
- priority
+ priority,
+ aggregateTriggerData,
+ aggregateValues
);
fail();
} catch (DatastoreException e) {
@@ -953,6 +1011,33 @@
static final Source.SourceType sSourceType = Source.SourceType.EVENT;
static final @Source.AttributionMode int sAttributionMode =
Source.AttributionMode.TRUTHFULLY;
+
+ static String buildAggregateSource() {
+ try {
+ JSONArray aggregatableSource = new JSONArray();
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put("id", "campaignCounts");
+ jsonObject.put("key_piece", "0x159");
+ aggregatableSource.put(jsonObject);
+ return aggregatableSource.toString();
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ static String buildAggregateFilterData() {
+ try {
+ JSONObject filterData = new JSONObject();
+ filterData.put("conversion_subdomain",
+ new JSONArray(Collections.singletonList("electronics.megastore")));
+ filterData.put("product", new JSONArray(Arrays.asList("1234", "2345")));
+ return filterData.toString();
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
}
private static class ValidTriggerParams {
@@ -963,6 +1048,32 @@
static final Uri sAttributionDestination = Uri.parse("android-app://com.destination");
static final Uri sRegistrant = Uri.parse("android-app://com.registrant");
static final Uri sReportTo = Uri.parse("https://com.example");
+
+ static String buildAggregateTriggerData() {
+ try {
+ JSONArray triggerData = new JSONArray();
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put("key_piece", "0xA80");
+ jsonObject.put("source_keys", new JSONArray(Arrays.asList("geoValue", "noMatch")));
+ triggerData.put(jsonObject);
+ return triggerData.toString();
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ static String buildAggregateValues() {
+ try {
+ JSONObject values = new JSONObject();
+ values.put("campaignCounts", 32768);
+ values.put("geoValue", 1664);
+ return values.toString();
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
}
}
diff --git a/adservices/tests/unittest/service-core/src/com/android/adservices/service/measurement/registration/SourceFetcherTest.java b/adservices/tests/unittest/service-core/src/com/android/adservices/service/measurement/registration/SourceFetcherTest.java
index f185bbd..5bec52f 100644
--- a/adservices/tests/unittest/service-core/src/com/android/adservices/service/measurement/registration/SourceFetcherTest.java
+++ b/adservices/tests/unittest/service-core/src/com/android/adservices/service/measurement/registration/SourceFetcherTest.java
@@ -441,12 +441,12 @@
when(mUrlConnection.getHeaderFields())
.thenReturn(Map.of("Attribution-Reporting-Redirect", List.of(ALT_REGISTRATION)))
.thenReturn(Map.of("Attribution-Reporting-Register-Source",
- List.of("{\n"
- + " \"destination\": \"" + DEFAULT_DESTINATION + "\",\n"
- + " \"priority\": \"" + DEFAULT_PRIORITY + "\",\n"
- + " \"expiry\": \"" + DEFAULT_EXPIRY + "\",\n"
- + " \"source_event_id\": \"" + DEFAULT_EVENT_ID + "\"\n"
- + "}\n")));
+ List.of("{\n"
+ + " \"destination\": \"" + DEFAULT_DESTINATION + "\",\n"
+ + " \"priority\": \"" + DEFAULT_PRIORITY + "\",\n"
+ + " \"expiry\": \"" + DEFAULT_EXPIRY + "\",\n"
+ + " \"source_event_id\": \"" + DEFAULT_EVENT_ID + "\"\n"
+ + "}\n")));
ArrayList<SourceRegistration> result = new ArrayList();
assertFalse(mFetcher.fetchSource(request, result));
@@ -454,6 +454,57 @@
verify(mUrlConnection, times(1)).setRequestMethod("POST");
}
+ @Test
+ public void testBasicSourceRequestWithAggregateFilterData() throws Exception {
+ RegistrationRequest request = buildRequest(DEFAULT_REGISTRATION, DEFAULT_TOP_ORIGIN);
+ String filterData =
+ " \"filter_data\": {\"product\":[\"1234\",\"2345\"], \"ctid\":[\"id\"]} \n";
+ doReturn(mUrlConnection).when(mFetcher).openUrl(any(URL.class));
+ when(mUrlConnection.getResponseCode()).thenReturn(200);
+ when(mUrlConnection.getHeaderFields())
+ .thenReturn(Map.of("Attribution-Reporting-Register-Source",
+ List.of("{\n"
+ + " \"destination\": \"android-app://com.myapps\",\n"
+ + " \"priority\": \"123\",\n"
+ + " \"expiry\": \"456789\",\n"
+ + " \"source_event_id\": \"987654321\",\n"
+ + filterData
+ + "}\n")));
+ ArrayList<SourceRegistration> result = new ArrayList<>();
+ assertTrue(mFetcher.fetchSource(request, result));
+ assertEquals(1, result.size());
+ assertEquals("https://baz.com", result.get(0).getTopOrigin().toString());
+ assertEquals("https://foo.com", result.get(0).getReportingOrigin().toString());
+ assertEquals("android-app://com.myapps", result.get(0).getDestination().toString());
+ assertEquals(123, result.get(0).getSourcePriority());
+ assertEquals(456789, result.get(0).getExpiry());
+ assertEquals(987654321, result.get(0).getSourceEventId());
+ assertEquals("{\"product\":[\"1234\",\"2345\"],\"ctid\":[\"id\"]}",
+ result.get(0).getAggregateFilterData());
+ verify(mUrlConnection).setRequestMethod("POST");
+ }
+
+ @Test
+ public void testBasicSourceRequestWithAggregateSource() throws Exception {
+ RegistrationRequest request = buildRequest(DEFAULT_REGISTRATION, DEFAULT_TOP_ORIGIN);
+ doReturn(mUrlConnection).when(mFetcher).openUrl(any(URL.class));
+ when(mUrlConnection.getResponseCode()).thenReturn(200);
+ when(mUrlConnection.getHeaderFields())
+ .thenReturn(Map.of("Attribution-Reporting-Register-Aggregatable-Source",
+ List.of("[{\"id\" : \"campaignCounts\", \"key_piece\" : \"0x159\"},"
+ + "{\"id\" : \"geoValue\", \"key_piece\" : \"0x5\"}]")));
+ ArrayList<SourceRegistration> result = new ArrayList<>();
+ assertTrue(mFetcher.fetchSource(request, result));
+ assertEquals(1, result.size());
+ assertEquals("https://baz.com", result.get(0).getTopOrigin().toString());
+ assertEquals("https://foo.com", result.get(0).getReportingOrigin().toString());
+ assertEquals(
+ "[{\"id\" : \"campaignCounts\", \"key_piece\" : \"0x159\"},{\"id\" : "
+ + "\"geoValue\", \"key_piece\" : \"0x5\"}]",
+ result.get(0).getAggregateSource());
+ verify(mUrlConnection).setRequestMethod("POST");
+ }
+
private RegistrationRequest buildRequest(String registrationUri, String topOrigin) {
return new RegistrationRequest.Builder()
.setRegistrationType(RegistrationRequest.REGISTER_SOURCE)
@@ -462,4 +513,4 @@
.setAttributionSource(sContext.getAttributionSource())
.build();
}
-}
+}
\ No newline at end of file
diff --git a/adservices/tests/unittest/service-core/src/com/android/adservices/service/measurement/registration/SourceRegistrationTest.java b/adservices/tests/unittest/service-core/src/com/android/adservices/service/measurement/registration/SourceRegistrationTest.java
index 423ef9e..91fc62b 100644
--- a/adservices/tests/unittest/service-core/src/com/android/adservices/service/measurement/registration/SourceRegistrationTest.java
+++ b/adservices/tests/unittest/service-core/src/com/android/adservices/service/measurement/registration/SourceRegistrationTest.java
@@ -18,6 +18,7 @@
import static com.android.adservices.service.measurement.PrivacyParams.MAX_REPORTING_REGISTER_SOURCE_EXPIRATION_IN_SECONDS;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
import android.content.Context;
import android.net.Uri;
@@ -39,13 +40,16 @@
private SourceRegistration createExampleResponse() {
return new SourceRegistration.Builder()
- .setTopOrigin(Uri.parse("https://foo.com"))
- .setReportingOrigin(Uri.parse("https://bar.com"))
- .setDestination(Uri.parse("android-app://baz.com"))
- .setSourceEventId(1234567)
- .setExpiry(2345678)
- .setSourcePriority(345678)
- .build();
+ .setTopOrigin(Uri.parse("https://foo.com"))
+ .setReportingOrigin(Uri.parse("https://bar.com"))
+ .setDestination(Uri.parse("android-app://baz.com"))
+ .setSourceEventId(1234567)
+ .setExpiry(2345678)
+ .setSourcePriority(345678)
+ .setAggregateSource("[{\"id\" : \"campaignCounts\", \"key_piece\" : \"0x159\"},"
+ + "{\"id\" : \"geoValue\", \"key_piece\" : \"0x5\"}]")
+ .setAggregateFilterData("{\"product\":[\"1234\",\"2345\"],\"ctid\":[\"id\"]}")
+ .build();
}
void verifyExampleResponse(SourceRegistration response) {
@@ -55,6 +59,11 @@
assertEquals(1234567, response.getSourceEventId());
assertEquals(2345678, response.getExpiry());
assertEquals(345678, response.getSourcePriority());
+ assertEquals("[{\"id\" : \"campaignCounts\", \"key_piece\" : \"0x159\"},"
+ + "{\"id\" : \"geoValue\", \"key_piece\" : \"0x5\"}]",
+ response.getAggregateSource());
+ assertEquals("{\"product\":[\"1234\",\"2345\"],\"ctid\":[\"id\"]}",
+ response.getAggregateFilterData());
}
@Test
@@ -71,5 +80,7 @@
assertEquals(0, response.getSourceEventId());
assertEquals(MAX_REPORTING_REGISTER_SOURCE_EXPIRATION_IN_SECONDS, response.getExpiry());
assertEquals(0, response.getSourcePriority());
+ assertNull(response.getAggregateSource());
+ assertNull(response.getAggregateFilterData());
}
}
diff --git a/adservices/tests/unittest/service-core/src/com/android/adservices/service/measurement/registration/TriggerFetcherTest.java b/adservices/tests/unittest/service-core/src/com/android/adservices/service/measurement/registration/TriggerFetcherTest.java
index 3551fcf..357662d 100644
--- a/adservices/tests/unittest/service-core/src/com/android/adservices/service/measurement/registration/TriggerFetcherTest.java
+++ b/adservices/tests/unittest/service-core/src/com/android/adservices/service/measurement/registration/TriggerFetcherTest.java
@@ -269,6 +269,50 @@
verify(mUrlConnection).setRequestMethod("POST");
}
+ @Test
+ public void testBasicTriggerRequestWithAggregateTriggerData() throws Exception {
+ RegistrationRequest request = buildRequest(TRIGGER_URI, TOP_ORIGIN);
+ doReturn(mUrlConnection).when(mFetcher).openUrl(new URL(TRIGGER_URI));
+ when(mUrlConnection.getResponseCode()).thenReturn(200);
+ when(mUrlConnection.getHeaderFields())
+ .thenReturn(Map.of("Attribution-Reporting-Register-Aggregatable-Trigger-Data",
+ List.of("[{\"key_piece\":\"0x400\",\"source_keys\":[\"campaignCounts\"],"
+ + "\"filters\":"
+ + "{\"conversion_subdomain\":[\"electronics.megastore\"]},"
+ + "\"not_filters\":{\"product\":[\"1\"]}},"
+ + "{\"key_piece\":\"0xA80\",\"source_keys\":[\"geoValue\"]}]")));
+ ArrayList<TriggerRegistration> result = new ArrayList<>();
+ assertTrue(mFetcher.fetchTrigger(request, result));
+ assertEquals(1, result.size());
+ assertEquals("https://baz.com", result.get(0).getTopOrigin().toString());
+ assertEquals("https://foo.com", result.get(0).getReportingOrigin().toString());
+ assertEquals(
+ "[{\"key_piece\":\"0x400\",\"source_keys\":[\"campaignCounts\"],"
+ + "\"filters\":{\"conversion_subdomain\":[\"electronics.megastore\"]},"
+ + "\"not_filters\":{\"product\":[\"1\"]}},"
+ + "{\"key_piece\":\"0xA80\",\"source_keys\":[\"geoValue\"]}]",
+ result.get(0).getAggregateTriggerData());
+ verify(mUrlConnection).setRequestMethod("POST");
+ }
+
+ @Test
+ public void testBasicTriggerRequestWithAggregateValues() throws Exception {
+ RegistrationRequest request = buildRequest(TRIGGER_URI, TOP_ORIGIN);
+ doReturn(mUrlConnection).when(mFetcher).openUrl(new URL(TRIGGER_URI));
+ when(mUrlConnection.getResponseCode()).thenReturn(200);
+ when(mUrlConnection.getHeaderFields())
+ .thenReturn(Map.of("Attribution-Reporting-Register-Aggregatable-Values",
+ List.of("{\"campaignCounts\":32768,\"geoValue\":1644}")));
+ ArrayList<TriggerRegistration> result = new ArrayList<>();
+ assertTrue(mFetcher.fetchTrigger(request, result));
+ assertEquals(1, result.size());
+ assertEquals("https://baz.com", result.get(0).getTopOrigin().toString());
+ assertEquals("https://foo.com", result.get(0).getReportingOrigin().toString());
+ assertEquals("{\"campaignCounts\":32768,\"geoValue\":1644}",
+ result.get(0).getAggregateValues());
+ verify(mUrlConnection).setRequestMethod("POST");
+ }
+
private RegistrationRequest buildRequest(String triggerUri, String topOriginUri) {
return new RegistrationRequest.Builder()
.setRegistrationType(RegistrationRequest.REGISTER_TRIGGER)
diff --git a/adservices/tests/unittest/service-core/src/com/android/adservices/service/measurement/registration/TriggerRegistrationTest.java b/adservices/tests/unittest/service-core/src/com/android/adservices/service/measurement/registration/TriggerRegistrationTest.java
index 233d97e..b46a032 100644
--- a/adservices/tests/unittest/service-core/src/com/android/adservices/service/measurement/registration/TriggerRegistrationTest.java
+++ b/adservices/tests/unittest/service-core/src/com/android/adservices/service/measurement/registration/TriggerRegistrationTest.java
@@ -43,6 +43,11 @@
.setTriggerData(1)
.setTriggerPriority(345678)
.setDeduplicationKey(2345678)
+ .setAggregateTriggerData(
+ "[{\"key_piece\":\"0x400\",\"source_keys\":[\"campaignCounts\"],"
+ + "\"not_filters\":{\"product\":[\"1\"]}},"
+ + "{\"key_piece\":\"0xA80\",\"source_keys\":[\"geoValue\"]}]")
+ .setAggregateValues("{\"campaignCounts\":32768,\"geoValue\":1644}")
.build();
}
@@ -52,6 +57,12 @@
assertEquals(1, response.getTriggerData());
assertEquals(345678, response.getTriggerPriority());
assertEquals(2345678, response.getDeduplicationKey().longValue());
+ assertEquals("[{\"key_piece\":\"0x400\",\"source_keys\":[\"campaignCounts\"],"
+ + "\"not_filters\":{\"product\":[\"1\"]}},"
+ + "{\"key_piece\":\"0xA80\",\"source_keys\":[\"geoValue\"]}]",
+ response.getAggregateTriggerData());
+ assertEquals("{\"campaignCounts\":32768,\"geoValue\":1644}",
+ response.getAggregateValues());
}
@Test
@@ -67,5 +78,7 @@
assertEquals(0, response.getTriggerData());
assertEquals(0, response.getTriggerPriority());
assertNull(response.getDeduplicationKey());
+ assertNull(response.getAggregateTriggerData());
+ assertNull(response.getAggregateValues());
}
}