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());
     }
 }