summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGilad Barkan <giladbarkan@google.com>2023-07-12 21:56:52 +0000
committerGilad Barkan <giladbarkan@google.com>2023-07-13 00:11:50 +0000
commiteab6f64aad5c7173c15f1c9d6fd197b0f291a0c3 (patch)
treecce471b34e1cf9f21b979602c4b55fd55f3de2ed
parent86eefbc8679c45a1731177ad0627b3a0c56c8d8c (diff)
downloadAdServices-eab6f64aad5c7173c15f1c9d6fd197b0f291a0c3.tar.gz
Measurement deletion of async registration records
Bug: 281699821 Bug: 290984420 Test: atest com.android.adservices.data.measurement Change-Id: I3e2b31b5625f8a34047b768b8d8cb1ac802a02a6
-rw-r--r--adservices/service-core/java/com/android/adservices/data/measurement/IMeasurementDao.java44
-rw-r--r--adservices/service-core/java/com/android/adservices/data/measurement/MeasurementDao.java72
-rw-r--r--adservices/service-core/java/com/android/adservices/data/measurement/deletion/MeasurementDataDeleter.java12
-rw-r--r--adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/registrant_not_found.json72
-rw-r--r--adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_multiple_origin_no_domain.json57
-rw-r--r--adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_multiple_origin_no_domain_preserve.json57
-rw-r--r--adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_no_origin_multiple_domain.json57
-rw-r--r--adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_no_origin_multiple_domain_preserve.json57
-rw-r--r--adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_no_origin_nor_range.json72
-rw-r--r--adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_origin_but_no_range.json55
-rw-r--r--adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_range_but_no_origin.json72
-rw-r--r--adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_range_on_ending_edge_and_origin.json55
-rw-r--r--adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_range_on_ending_edge_no_origin.json72
-rw-r--r--adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_range_on_starting_edge_and_origin.json55
-rw-r--r--adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_range_on_starting_edge_no_origin.json72
-rw-r--r--adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_start_equals_end_and_origin.json55
-rw-r--r--adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_start_equals_end_no_origin_preserve.json55
-rw-r--r--adservices/tests/unittest/service-core/src/com/android/adservices/data/measurement/AbstractDbIntegrationTest.java74
-rw-r--r--adservices/tests/unittest/service-core/src/com/android/adservices/data/measurement/DbState.java53
-rw-r--r--adservices/tests/unittest/service-core/src/com/android/adservices/data/measurement/MeasurementDaoTest.java267
-rw-r--r--adservices/tests/unittest/service-core/src/com/android/adservices/data/measurement/deletion/MeasurementDataDeleterTest.java11
21 files changed, 1330 insertions, 66 deletions
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 a232178386..fe063b50f7 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
@@ -416,21 +416,21 @@ public interface IMeasurementDao {
void deleteSources(@NonNull List<String> sourceIds) throws DatastoreException;
/**
- * Delete records from Async Registration table whose registrant or app destination match with
- * provided app URI.
+ * Delete records from trigger table that match provided trigger IDs.
*
- * @param uri AsyncRegistrations registrant or OS Destination to match
+ * @param triggerIds trigger IDs to match
* @throws DatastoreException database transaction issues
*/
- void deleteAsyncRegistrationsProvidedRegistrant(@NonNull String uri) throws DatastoreException;
+ void deleteTriggers(@NonNull List<String> triggerIds) throws DatastoreException;
/**
- * Delete records from source table that match provided trigger IDs.
+ * Delete records from async registration table that match provided async registration IDs.
*
- * @param triggerIds trigger IDs to match
+ * @param asyncRegistrationIds async registration IDs to match
* @throws DatastoreException database transaction issues
*/
- void deleteTriggers(@NonNull List<String> triggerIds) throws DatastoreException;
+ void deleteAsyncRegistrations(@NonNull List<String> asyncRegistrationIds)
+ throws DatastoreException;
/**
* Insert a record into the Async Registration Table.
@@ -554,7 +554,7 @@ public interface IMeasurementDao {
throws DatastoreException;
/**
- * Returns list of triggers matching registrant, publishers and also in the provided time frame.
+ * Returns list of triggers matching registrant and destinations in the provided time frame.
* It matches registrant and time range (start & end) irrespective of the {@code matchBehavior}.
* In the resulting set, if matchBehavior is {@link
* android.adservices.measurement.DeletionRequest.MatchBehavior#MATCH_BEHAVIOR_DELETE}, then it
@@ -582,6 +582,34 @@ public interface IMeasurementDao {
throws DatastoreException;
/**
+ * Returns list of async registrations matching registrant and top origins in the provided time
+ * frame. It matches registrant and time range (start & end) irrespective of the {@code
+ * matchBehavior}. In the resulting set, if matchBehavior is {@link
+ * android.adservices.measurement.DeletionRequest.MatchBehavior#MATCH_BEHAVIOR_DELETE}, then it
+ * matches origins and domains. In case of {@link
+ * android.adservices.measurement.DeletionRequest.MatchBehavior#MATCH_BEHAVIOR_PRESERVE}, it
+ * returns the records that don't match origins or domain.
+ *
+ * @param registrant registrant to match
+ * @param start request time should be after this instant (inclusive)
+ * @param end request time should be after this instant (inclusive)
+ * @param origins top origin site match
+ * @param domains top origin top level domain matches
+ * @param matchBehavior indicates whether to return matching or inversely matching (everything
+ * except matching) data
+ * @return list of async registration IDs
+ * @throws DatastoreException database transaction level issues
+ */
+ List<String> fetchMatchingAsyncRegistrations(
+ @NonNull Uri registrant,
+ @NonNull Instant start,
+ @NonNull Instant end,
+ @NonNull List<Uri> origins,
+ @NonNull List<Uri> domains,
+ @DeletionRequest.MatchBehavior int matchBehavior)
+ throws DatastoreException;
+
+ /**
* Fetches the XNA relevant sources. It includes sources associated to the trigger's enrollment
* ID as well as the sources associated to the provided SAN enrollment IDs.
*
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 a1b7aedb59..9a7b92e9d0 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
@@ -1719,6 +1719,54 @@ class MeasurementDao implements IMeasurementDao {
return triggerIds.build();
}
+ @Override
+ public List<String> fetchMatchingAsyncRegistrations(
+ @NonNull Uri registrant,
+ @NonNull Instant start,
+ @NonNull Instant end,
+ @NonNull List<Uri> origins,
+ @NonNull List<Uri> domains,
+ // TODO: change this to selection and invert selection mode
+ @DeletionRequest.MatchBehavior int matchBehavior)
+ throws DatastoreException {
+ Objects.requireNonNull(registrant);
+ Objects.requireNonNull(origins);
+ Objects.requireNonNull(domains);
+ Objects.requireNonNull(start);
+ Objects.requireNonNull(end);
+ validateRange(start, end);
+ Instant cappedStart = capDeletionRange(start);
+ Instant cappedEnd = capDeletionRange(end);
+ Function<String, String> registrantMatcher = getRegistrantMatcher(registrant);
+ Function<String, String> siteMatcher = getSiteMatcher(origins, domains, matchBehavior);
+ Function<String, String> timeMatcher = getTimeMatcher(cappedStart, cappedEnd);
+
+ final SQLiteDatabase db = mSQLTransaction.getDatabase();
+ ImmutableList.Builder<String> asyncRegistrationIds = new ImmutableList.Builder<>();
+ try (Cursor cursor =
+ db.query(
+ MeasurementTables.AsyncRegistrationContract.TABLE,
+ new String[] {MeasurementTables.AsyncRegistrationContract.ID},
+ mergeConditions(
+ " AND ",
+ registrantMatcher.apply(
+ MeasurementTables.AsyncRegistrationContract.REGISTRANT),
+ siteMatcher.apply(
+ MeasurementTables.AsyncRegistrationContract.TOP_ORIGIN),
+ timeMatcher.apply(
+ MeasurementTables.AsyncRegistrationContract.REQUEST_TIME)),
+ null,
+ null,
+ null,
+ null)) {
+ while (cursor.moveToNext()) {
+ asyncRegistrationIds.add(cursor.getString(0));
+ }
+ }
+
+ return asyncRegistrationIds.build();
+ }
+
private static Function<String, String> getRegistrantMatcher(Uri registrant) {
return (String columnName) ->
columnName + " = " + DatabaseUtils.sqlEscapeString(registrant.toString());
@@ -2252,6 +2300,15 @@ class MeasurementDao implements IMeasurementDao {
MeasurementTables.TriggerContract.ID);
}
+ @Override
+ public void deleteAsyncRegistrations(@NonNull List<String> asyncRegistrationIds)
+ throws DatastoreException {
+ deleteRecordsColumnBased(
+ asyncRegistrationIds,
+ MeasurementTables.AsyncRegistrationContract.TABLE,
+ MeasurementTables.AsyncRegistrationContract.ID);
+ }
+
private void deleteRecordsColumnBased(
List<String> columnValues, String tableName, String columnName)
throws DatastoreException {
@@ -2568,21 +2625,6 @@ class MeasurementDao implements IMeasurementDao {
}
@Override
- public void deleteAsyncRegistrationsProvidedRegistrant(@NonNull String uri)
- throws DatastoreException {
- SQLiteDatabase db = mSQLTransaction.getDatabase();
- int rows =
- db.delete(
- MeasurementTables.AsyncRegistrationContract.TABLE,
- MeasurementTables.AsyncRegistrationContract.REGISTRANT + " = ? ",
- new String[] {uri});
- LogUtil.d(
- "MeasurementDao: deleteAsyncRegistrationsProvidedRegistrant: rows"
- + " affected="
- + rows);
- }
-
- @Override
public AsyncRegistration fetchNextQueuedAsyncRegistration(
int retryLimit, Set<Uri> failedOrigins) throws DatastoreException {
String originExclusion = "";
diff --git a/adservices/service-core/java/com/android/adservices/data/measurement/deletion/MeasurementDataDeleter.java b/adservices/service-core/java/com/android/adservices/data/measurement/deletion/MeasurementDataDeleter.java
index f186d164d0..68dfe97da5 100644
--- a/adservices/service-core/java/com/android/adservices/data/measurement/deletion/MeasurementDataDeleter.java
+++ b/adservices/service-core/java/com/android/adservices/data/measurement/deletion/MeasurementDataDeleter.java
@@ -90,6 +90,14 @@ public class MeasurementDataDeleter {
deletionParam.getOriginUris(),
deletionParam.getDomainUris(),
deletionParam.getMatchBehavior());
+ List<String> asyncRegistrationIds =
+ dao.fetchMatchingAsyncRegistrations(
+ getRegistrant(deletionParam.getAppPackageName()),
+ deletionParam.getStart(),
+ deletionParam.getEnd(),
+ deletionParam.getOriginUris(),
+ deletionParam.getDomainUris(),
+ deletionParam.getMatchBehavior());
// Rest aggregate contributions and dedup keys on sources for triggers to be
// deleted.
@@ -141,9 +149,7 @@ public class MeasurementDataDeleter {
resetDedupKeys(dao, eventReports);
- // Delete Async Registration Table Data
- dao.deleteAsyncRegistrationsProvidedRegistrant(
- deletionParam.getAppPackageName());
+ dao.deleteAsyncRegistrations(asyncRegistrationIds);
// Delete sources and triggers, that'll take care of deleting related reports
// and attributions
diff --git a/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/registrant_not_found.json b/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/registrant_not_found.json
index 6be959149e..c5e9d4b564 100644
--- a/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/registrant_not_found.json
+++ b/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/registrant_not_found.json
@@ -126,6 +126,42 @@
"triggerId": "T2",
"registrant": "android-app://com.registrant2"
}
+ ],
+ "async_registrations": [
+ {
+ "registrationId": "AR1",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "https://foo.com",
+ "registrant": "android-app://com.registrant1",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733601,
+ "adIdPermission": false,
+ "id": "id1",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ },
+ {
+ "registrationId": "AR2",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "https://foo.com",
+ "registrant": "android-app://com.registrant2",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733601,
+ "adIdPermission": false,
+ "id": "id2",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ }
]
},
"output": {
@@ -254,6 +290,42 @@
"triggerId": "T2",
"registrant": "android-app://com.registrant2"
}
+ ],
+ "async_registrations": [
+ {
+ "registrationId": "AR1",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "https://foo.com",
+ "registrant": "android-app://com.registrant1",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733601,
+ "adIdPermission": false,
+ "id": "id1",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ },
+ {
+ "registrationId": "AR2",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "https://foo.com",
+ "registrant": "android-app://com.registrant2",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733601,
+ "adIdPermission": false,
+ "id": "id2",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ }
]
},
"param": {
diff --git a/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_multiple_origin_no_domain.json b/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_multiple_origin_no_domain.json
index 2c3de6b045..c9b7e17e1a 100644
--- a/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_multiple_origin_no_domain.json
+++ b/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_multiple_origin_no_domain.json
@@ -1,6 +1,6 @@
{
"name": "With multiple origin and no domain",
- "description": "(S1,S4), (T1, T4), (E1,E2, E4, E6) AND (A1,A4) will be deleted due to origin match. S2,T2,E5,A2 skipped as they are out of time range.",
+ "description": "(S1,S4), (T1, T4), (E1,E2, E4, E6), (A1,A4), and (AR1) will be deleted due to origin match. S2,T2,E5,A2,AR2 skipped as they are out of time range.",
"input": {
"sources": [
{
@@ -295,6 +295,42 @@
"sourceId": "S2",
"triggerId": "T4"
}
+ ],
+ "async_registrations": [
+ {
+ "registrationId": "AR1",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "https://deleteCandidate1.site.test",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733601,
+ "adIdPermission": false,
+ "id": "id1",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ },
+ {
+ "registrationId": "AR2",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "https://deleteCandidate2.site.test",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733605,
+ "adIdPermission": false,
+ "id": "id2",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ }
]
},
"output": {
@@ -435,6 +471,25 @@
"sourceId": "S3",
"triggerId": "T3"
}
+ ],
+ "async_registrations": [
+ {
+ "registrationId": "AR2",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "https://deleteCandidate2.site.test",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733605,
+ "adIdPermission": false,
+ "id": "id2",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ }
]
},
"param": {
diff --git a/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_multiple_origin_no_domain_preserve.json b/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_multiple_origin_no_domain_preserve.json
index defd80897d..533129bd50 100644
--- a/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_multiple_origin_no_domain_preserve.json
+++ b/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_multiple_origin_no_domain_preserve.json
@@ -1,6 +1,6 @@
{
"name": "With multiple origin and no domain - preserve",
- "description": "(S3), (T3), (E3) AND (A2, A3, A5) will be deleted due to mismatched origins. E2 not delete as it is out of range",
+ "description": "(S3), (T3), (E3), (A2, A3, A5), and (AR1) will be deleted due to mismatched origins. E2, AR2 not delete as it is out of range",
"input": {
"sources": [
{
@@ -308,6 +308,42 @@
"sourceId": "S3",
"triggerId": "T4"
}
+ ],
+ "async_registrations": [
+ {
+ "registrationId": "AR1",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "https://unmatched.site.test",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733601,
+ "adIdPermission": false,
+ "id": "id1",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ },
+ {
+ "registrationId": "AR2",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "https://deleteCandidate2.site.test",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733605,
+ "adIdPermission": false,
+ "id": "id2",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ }
]
},
"output": {
@@ -527,6 +563,25 @@
"sourceId": "S2",
"triggerId": "T4"
}
+ ],
+ "async_registrations": [
+ {
+ "registrationId": "AR2",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "https://deleteCandidate2.site.test",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733605,
+ "adIdPermission": false,
+ "id": "id2",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ }
]
},
"param": {
diff --git a/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_no_origin_multiple_domain.json b/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_no_origin_multiple_domain.json
index afcc5a3069..abd601f823 100644
--- a/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_no_origin_multiple_domain.json
+++ b/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_no_origin_multiple_domain.json
@@ -1,6 +1,6 @@
{
"name": "With no origin and multiple domain",
- "description": "(S1, S4), (T1, T4), (E1, E2(due to S1), E3, E4, E6) and (A1, A4) deleted due to origin match; S2, T2, E5, A2 skipped due to being out of range.",
+ "description": "(S1, S4), (T1, T4), (E1, E2(due to S1), E3, E4, E6), (A1, A4), and (AR1) deleted due to site match; S2, T2, E5, A2, AR2 skipped due to being out of range.",
"input": {
"sources": [
{
@@ -308,6 +308,42 @@
"sourceId" : "S3",
"triggerId" : "T2"
}
+ ],
+ "async_registrations": [
+ {
+ "registrationId": "AR1",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "https://deleteCandidate1.site.test",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733601,
+ "adIdPermission": false,
+ "id": "id1",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ },
+ {
+ "registrationId": "AR2",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "https://deleteCandidate2.site.test",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733605,
+ "adIdPermission": false,
+ "id": "id2",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ }
]
},
"output": {
@@ -447,6 +483,25 @@
"sourceId" : "S3",
"triggerId" : "T2"
}
+ ],
+ "async_registrations": [
+ {
+ "registrationId": "AR2",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "https://deleteCandidate2.site.test",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733605,
+ "adIdPermission": false,
+ "id": "id2",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ }
]
},
"param": {
diff --git a/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_no_origin_multiple_domain_preserve.json b/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_no_origin_multiple_domain_preserve.json
index 349e2c3462..802e383195 100644
--- a/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_no_origin_multiple_domain_preserve.json
+++ b/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_no_origin_multiple_domain_preserve.json
@@ -1,6 +1,6 @@
{
"name": "With no origin and multiple domain - preserve",
- "description": "(S3), (T3), (E7) and (A1,A3, A4, A5) deleted due to origin mismatch; S2, T2, E5, A2 skipped due to being out of range.",
+ "description": "(S3), (T3), (E7), (A1,A3, A4, A5) and (AR1) deleted due to site mismatch; S2, T2, E5, A2, AR2 skipped due to being out of range.",
"input": {
"sources": [
{
@@ -322,6 +322,42 @@
"sourceId": "S3",
"triggerId": "T3"
}
+ ],
+ "async_registrations": [
+ {
+ "registrationId": "AR1",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "https://deleteCandidate1.unmatched_site.test",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733601,
+ "adIdPermission": false,
+ "id": "id1",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ },
+ {
+ "registrationId": "AR2",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "https://deleteCandidate2.site.test",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733605,
+ "adIdPermission": false,
+ "id": "id2",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ }
]
},
"output": {
@@ -542,6 +578,25 @@
"sourceId": "S2",
"triggerId": "T2"
}
+ ],
+ "async_registrations": [
+ {
+ "registrationId": "AR2",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "https://deleteCandidate2.site.test",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733605,
+ "adIdPermission": false,
+ "id": "id2",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ }
]
},
"param": {
diff --git a/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_no_origin_nor_range.json b/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_no_origin_nor_range.json
index bfab386bcf..5ed787715e 100644
--- a/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_no_origin_nor_range.json
+++ b/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_no_origin_nor_range.json
@@ -135,6 +135,42 @@
"sourceId": "S2",
"triggerId": "T2"
}
+ ],
+ "async_registrations": [
+ {
+ "registrationId": "AR1",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "https://deleteCandidate1.site.test",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733601,
+ "adIdPermission": false,
+ "id": "id1",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ },
+ {
+ "registrationId": "AR2",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "https://deleteCandidate2.site.test",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733605,
+ "adIdPermission": false,
+ "id": "id2",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ }
]
},
"output": {
@@ -271,6 +307,42 @@
"sourceId": "S2",
"triggerId": "T2"
}
+ ],
+ "async_registrations": [
+ {
+ "registrationId": "AR1",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "https://deleteCandidate1.site.test",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733601,
+ "adIdPermission": false,
+ "id": "id1",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ },
+ {
+ "registrationId": "AR2",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "https://deleteCandidate2.site.test",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733605,
+ "adIdPermission": false,
+ "id": "id2",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ }
]
},
"param": {
diff --git a/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_origin_but_no_range.json b/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_origin_but_no_range.json
index 6000ba2e53..0528d34e84 100644
--- a/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_origin_but_no_range.json
+++ b/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_origin_but_no_range.json
@@ -161,6 +161,42 @@
"sourceId": "S2",
"triggerId": "T2"
}
+ ],
+ "async_registrations": [
+ {
+ "registrationId": "AR1",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "https://deleteCandidate1.site.test",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733601,
+ "adIdPermission": false,
+ "id": "id1",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ },
+ {
+ "registrationId": "AR2",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "android-app://com.site.toBeDeleted",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733605,
+ "adIdPermission": false,
+ "id": "id2",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ }
]
},
"output": {
@@ -235,6 +271,25 @@
"sourceId": "S2",
"triggerId": "T2"
}
+ ],
+ "async_registrations": [
+ {
+ "registrationId": "AR1",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "https://deleteCandidate1.site.test",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733601,
+ "adIdPermission": false,
+ "id": "id1",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ }
]
},
"param": {
diff --git a/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_range_but_no_origin.json b/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_range_but_no_origin.json
index e02ade2743..2f08f9ea86 100644
--- a/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_range_but_no_origin.json
+++ b/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_range_but_no_origin.json
@@ -153,6 +153,42 @@
"sourceId": "S2",
"triggerId": "T2"
}
+ ],
+ "async_registrations": [
+ {
+ "registrationId": "AR1",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "https://deleteCandidate1.site.test",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733601,
+ "adIdPermission": false,
+ "id": "id1",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ },
+ {
+ "registrationId": "AR2",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "android-app://com.site.toBeDeleted",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733605,
+ "adIdPermission": false,
+ "id": "id2",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ }
]
},
"output": {
@@ -307,6 +343,42 @@
"sourceId": "S2",
"triggerId": "T2"
}
+ ],
+ "async_registrations": [
+ {
+ "registrationId": "AR1",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "https://deleteCandidate1.site.test",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733601,
+ "adIdPermission": false,
+ "id": "id1",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ },
+ {
+ "registrationId": "AR2",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "android-app://com.site.toBeDeleted",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733605,
+ "adIdPermission": false,
+ "id": "id2",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ }
]
},
"param": {
diff --git a/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_range_on_ending_edge_and_origin.json b/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_range_on_ending_edge_and_origin.json
index 5231899322..74b7ca85a9 100644
--- a/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_range_on_ending_edge_and_origin.json
+++ b/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_range_on_ending_edge_and_origin.json
@@ -230,6 +230,42 @@
"sourceId": "S3",
"triggerId": "T3"
}
+ ],
+ "async_registrations": [
+ {
+ "registrationId": "AR1",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "android-app://com.site.deleteCandidate",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733602,
+ "adIdPermission": false,
+ "id": "id1",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ },
+ {
+ "registrationId": "AR2",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "android-app://com.site.deleteCandidate",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733605,
+ "adIdPermission": false,
+ "id": "id2",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ }
]
},
"output": {
@@ -370,6 +406,25 @@
"sourceId": "S3",
"triggerId": "T3"
}
+ ],
+ "async_registrations": [
+ {
+ "registrationId": "AR2",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "android-app://com.site.deleteCandidate",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733605,
+ "adIdPermission": false,
+ "id": "id2",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ }
]
},
"param": {
diff --git a/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_range_on_ending_edge_no_origin.json b/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_range_on_ending_edge_no_origin.json
index 38162570cc..6aa23b0530 100644
--- a/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_range_on_ending_edge_no_origin.json
+++ b/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_range_on_ending_edge_no_origin.json
@@ -153,6 +153,42 @@
"sourceId": "S2",
"triggerId": "T2"
}
+ ],
+ "async_registrations": [
+ {
+ "registrationId": "AR1",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "android-app://com.site.deleteCandidate",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733602,
+ "adIdPermission": false,
+ "id": "id1",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ },
+ {
+ "registrationId": "AR2",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "android-app://com.site.deleteCandidate",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733605,
+ "adIdPermission": false,
+ "id": "id2",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ }
]
},
"output": {
@@ -307,6 +343,42 @@
"sourceId": "S2",
"triggerId": "T2"
}
+ ],
+ "async_registrations": [
+ {
+ "registrationId": "AR1",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "android-app://com.site.deleteCandidate",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733602,
+ "adIdPermission": false,
+ "id": "id1",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ },
+ {
+ "registrationId": "AR2",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "android-app://com.site.deleteCandidate",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733605,
+ "adIdPermission": false,
+ "id": "id2",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ }
]
},
"param": {
diff --git a/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_range_on_starting_edge_and_origin.json b/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_range_on_starting_edge_and_origin.json
index 04622031c6..bf15f2fe8f 100644
--- a/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_range_on_starting_edge_and_origin.json
+++ b/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_range_on_starting_edge_and_origin.json
@@ -217,6 +217,42 @@
"sourceId": "S2",
"triggerId": "T2"
}
+ ],
+ "async_registrations": [
+ {
+ "registrationId": "AR1",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "android-app://com.site.deleteCandidate",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733600,
+ "adIdPermission": false,
+ "id": "id1",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ },
+ {
+ "registrationId": "AR2",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "android-app://com.site.deleteCandidate",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733605,
+ "adIdPermission": false,
+ "id": "id2",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ }
]
},
"output": {
@@ -344,6 +380,25 @@
"sourceId": "S2",
"triggerId": "T2"
}
+ ],
+ "async_registrations": [
+ {
+ "registrationId": "AR2",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "android-app://com.site.deleteCandidate",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733605,
+ "adIdPermission": false,
+ "id": "id2",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ }
]
},
"param": {
diff --git a/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_range_on_starting_edge_no_origin.json b/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_range_on_starting_edge_no_origin.json
index 78e67e97c6..96e63cfafe 100644
--- a/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_range_on_starting_edge_no_origin.json
+++ b/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_range_on_starting_edge_no_origin.json
@@ -153,6 +153,42 @@
"sourceId": "S2",
"triggerId": "T2"
}
+ ],
+ "async_registrations": [
+ {
+ "registrationId": "AR1",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "android-app://com.site.deleteCandidate",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733600,
+ "adIdPermission": false,
+ "id": "id1",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ },
+ {
+ "registrationId": "AR2",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "android-app://com.site.deleteCandidate",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733605,
+ "adIdPermission": false,
+ "id": "id2",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ }
]
},
"output": {
@@ -307,6 +343,42 @@
"sourceId": "S2",
"triggerId": "T2"
}
+ ],
+ "async_registrations": [
+ {
+ "registrationId": "AR1",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "android-app://com.site.deleteCandidate",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733600,
+ "adIdPermission": false,
+ "id": "id1",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ },
+ {
+ "registrationId": "AR2",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "android-app://com.site.deleteCandidate",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733605,
+ "adIdPermission": false,
+ "id": "id2",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ }
]
},
"param": {
diff --git a/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_start_equals_end_and_origin.json b/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_start_equals_end_and_origin.json
index 1803664354..540f8cefda 100644
--- a/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_start_equals_end_and_origin.json
+++ b/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_start_equals_end_and_origin.json
@@ -217,6 +217,42 @@
"sourceId": "S2",
"triggerId": "T2"
}
+ ],
+ "async_registrations": [
+ {
+ "registrationId": "AR1",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "android-app://com.site.deleteCandidate",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733600,
+ "adIdPermission": false,
+ "id": "id1",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ },
+ {
+ "registrationId": "AR2",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "android-app://com.site.deleteCandidate",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733605,
+ "adIdPermission": false,
+ "id": "id2",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ }
]
},
"output": {
@@ -344,6 +380,25 @@
"sourceId": "S2",
"triggerId": "T2"
}
+ ],
+ "async_registrations": [
+ {
+ "registrationId": "AR2",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "android-app://com.site.deleteCandidate",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733605,
+ "adIdPermission": false,
+ "id": "id2",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ }
]
},
"param": {
diff --git a/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_start_equals_end_no_origin_preserve.json b/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_start_equals_end_no_origin_preserve.json
index 1427248d2a..0a4c0a3692 100644
--- a/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_start_equals_end_no_origin_preserve.json
+++ b/adservices/tests/unittest/service-core/assets/msmt_browser_deletion_tests/with_start_equals_end_no_origin_preserve.json
@@ -152,6 +152,42 @@
"sourceId": "S2",
"triggerId": "T2"
}
+ ],
+ "async_registrations": [
+ {
+ "registrationId": "AR1",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "android-app://com.site.deleteCandidate",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733600,
+ "adIdPermission": false,
+ "id": "id1",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ },
+ {
+ "registrationId": "AR2",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "android-app://com.site.deleteCandidate",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733605,
+ "adIdPermission": false,
+ "id": "id2",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ }
]
},
"output": {
@@ -228,6 +264,25 @@
"sourceId": "S2",
"triggerId": "T2"
}
+ ],
+ "async_registrations": [
+ {
+ "registrationId": "AR2",
+ "registrationUri": "https://foo.com",
+ "topOrigin": "android-app://com.site.deleteCandidate",
+ "registrant": "android-app://com.registrant.deleteCandidate",
+ "osDestination": "https://foo.com",
+ "requestTime": 1648665733605,
+ "adIdPermission": false,
+ "id": "id2",
+ "registrationType": 0,
+ "platformAdId": "platform",
+ "debugKeyAllowed": false,
+ "retryCount": 1,
+ "verifiedDestination": "https://foo.com",
+ "webDestination": "https://foo.com",
+ "sourceType": 1
+ }
]
},
"param": {
diff --git a/adservices/tests/unittest/service-core/src/com/android/adservices/data/measurement/AbstractDbIntegrationTest.java b/adservices/tests/unittest/service-core/src/com/android/adservices/data/measurement/AbstractDbIntegrationTest.java
index cebf93d1a8..c5c1d42b43 100644
--- a/adservices/tests/unittest/service-core/src/com/android/adservices/data/measurement/AbstractDbIntegrationTest.java
+++ b/adservices/tests/unittest/service-core/src/com/android/adservices/data/measurement/AbstractDbIntegrationTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,6 +32,7 @@ import com.android.adservices.service.measurement.Source;
import com.android.adservices.service.measurement.Trigger;
import com.android.adservices.service.measurement.aggregation.AggregateEncryptionKey;
import com.android.adservices.service.measurement.aggregation.AggregateReport;
+import com.android.adservices.service.measurement.registration.AsyncRegistration;
import com.android.adservices.service.measurement.util.UnsignedLong;
import com.android.dx.mockito.inline.extended.ExtendedMockito;
@@ -137,6 +138,9 @@ public abstract class AbstractDbIntegrationTest {
areEqual(mOutput.mSourceDestinationList, dbState.mSourceDestinationList));
Assert.assertTrue("Trigger mismatch",
areEqual(mOutput.mTriggerList, dbState.mTriggerList));
+ Assert.assertTrue(
+ "Async Registration mismatch",
+ areEqual(mOutput.mAsyncRegistrationList, dbState.mAsyncRegistrationList));
}
private boolean fuzzyCompareAggregateReport(
@@ -266,6 +270,7 @@ public abstract class AbstractDbIntegrationTest {
db.delete(MeasurementTables.AttributionContract.TABLE, null, null);
db.delete(MeasurementTables.AggregateReport.TABLE, null, null);
db.delete(MeasurementTables.AggregateEncryptionKey.TABLE, null, null);
+ db.delete(MeasurementTables.AsyncRegistrationContract.TABLE, null, null);
}
/**
@@ -294,6 +299,10 @@ public abstract class AbstractDbIntegrationTest {
for (AggregateEncryptionKey key : input.mAggregateEncryptionKeyList) {
insertToDb(key, db);
}
+
+ for (AsyncRegistration registration : input.mAsyncRegistrationList) {
+ insertToDb(registration, db);
+ }
}
/**
@@ -520,7 +529,70 @@ public abstract class AbstractDbIntegrationTest {
}
}
+ /** Inserts an AsyncRegistration record into the given database. */
+ private static void insertToDb(AsyncRegistration asyncRegistration, SQLiteDatabase db)
+ throws SQLiteException {
+ ContentValues values = new ContentValues();
+ values.put(MeasurementTables.AsyncRegistrationContract.ID, asyncRegistration.getId());
+ values.put(
+ MeasurementTables.AsyncRegistrationContract.REGISTRATION_URI,
+ asyncRegistration.getRegistrationUri().toString());
+ values.put(
+ MeasurementTables.AsyncRegistrationContract.WEB_DESTINATION,
+ getNullableUriString(asyncRegistration.getWebDestination()));
+ values.put(
+ MeasurementTables.AsyncRegistrationContract.VERIFIED_DESTINATION,
+ getNullableUriString(asyncRegistration.getVerifiedDestination()));
+ values.put(
+ MeasurementTables.AsyncRegistrationContract.OS_DESTINATION,
+ getNullableUriString(asyncRegistration.getOsDestination()));
+ values.put(
+ MeasurementTables.AsyncRegistrationContract.REGISTRANT,
+ getNullableUriString(asyncRegistration.getRegistrant()));
+ values.put(
+ MeasurementTables.AsyncRegistrationContract.TOP_ORIGIN,
+ getNullableUriString(asyncRegistration.getTopOrigin()));
+ values.put(
+ MeasurementTables.AsyncRegistrationContract.SOURCE_TYPE,
+ asyncRegistration.getSourceType() == null
+ ? null
+ : asyncRegistration.getSourceType().ordinal());
+ values.put(
+ MeasurementTables.AsyncRegistrationContract.REQUEST_TIME,
+ asyncRegistration.getRequestTime());
+ values.put(
+ MeasurementTables.AsyncRegistrationContract.RETRY_COUNT,
+ asyncRegistration.getRetryCount());
+ values.put(
+ MeasurementTables.AsyncRegistrationContract.TYPE,
+ asyncRegistration.getType().ordinal());
+ values.put(
+ MeasurementTables.AsyncRegistrationContract.DEBUG_KEY_ALLOWED,
+ asyncRegistration.getDebugKeyAllowed());
+ values.put(
+ MeasurementTables.AsyncRegistrationContract.AD_ID_PERMISSION,
+ asyncRegistration.hasAdIdPermission());
+ values.put(
+ MeasurementTables.AsyncRegistrationContract.REGISTRATION_ID,
+ asyncRegistration.getRegistrationId());
+ values.put(
+ MeasurementTables.AsyncRegistrationContract.PLATFORM_AD_ID,
+ asyncRegistration.getPlatformAdId());
+ long rowId =
+ db.insert(
+ MeasurementTables.AsyncRegistrationContract.TABLE,
+ /* nullColumnHack= */ null,
+ values);
+ if (rowId == -1) {
+ throw new SQLiteException("Async Registration insertion failed.");
+ }
+ }
+
private static Long getNullableUnsignedLong(UnsignedLong ulong) {
return Optional.ofNullable(ulong).map(UnsignedLong::getValue).orElse(null);
}
+
+ private static String getNullableUriString(Uri uri) {
+ return Optional.ofNullable(uri).map(Uri::toString).orElse(null);
+ }
}
diff --git a/adservices/tests/unittest/service-core/src/com/android/adservices/data/measurement/DbState.java b/adservices/tests/unittest/service-core/src/com/android/adservices/data/measurement/DbState.java
index 126708c25b..790e0b2998 100644
--- a/adservices/tests/unittest/service-core/src/com/android/adservices/data/measurement/DbState.java
+++ b/adservices/tests/unittest/service-core/src/com/android/adservices/data/measurement/DbState.java
@@ -27,6 +27,7 @@ import com.android.adservices.service.measurement.Trigger;
import com.android.adservices.service.measurement.WebUtil;
import com.android.adservices.service.measurement.aggregation.AggregateEncryptionKey;
import com.android.adservices.service.measurement.aggregation.AggregateReport;
+import com.android.adservices.service.measurement.registration.AsyncRegistration;
import com.android.adservices.service.measurement.reporting.DebugReport;
import com.android.adservices.service.measurement.util.UnsignedLong;
@@ -55,6 +56,7 @@ public class DbState {
List<AggregateEncryptionKey> mAggregateEncryptionKeyList;
List<AggregateReport> mAggregateReportList;
List<DebugReport> mDebugReportList;
+ List<AsyncRegistration> mAsyncRegistrationList;
public DbState() {
mSourceList = new ArrayList<>();
@@ -65,6 +67,7 @@ public class DbState {
mAggregateEncryptionKeyList = new ArrayList<>();
mAggregateReportList = new ArrayList<>();
mDebugReportList = new ArrayList<>();
+ mAsyncRegistrationList = new ArrayList<>();
}
public DbState(JSONObject testInput) throws JSONException {
@@ -149,6 +152,16 @@ public class DbState {
mDebugReportList.add(debugReport);
}
}
+
+ if (testInput.has("async_registrations")) {
+ // AsyncRegistrations
+ JSONArray asyncRegistrations = testInput.getJSONArray("async_registrations");
+ for (int i = 0; i < asyncRegistrations.length(); i++) {
+ JSONObject aJSON = asyncRegistrations.getJSONObject(i);
+ AsyncRegistration asyncRegistration = getAsyncRegistrationFrom(aJSON);
+ mAsyncRegistrationList.add(asyncRegistration);
+ }
+ }
}
public DbState(SQLiteDatabase readerDB) {
@@ -242,6 +255,22 @@ public class DbState {
SqliteObjectMapper.constructDebugReportFromCursor(debugReportCursor));
}
debugReportCursor.close();
+
+ // Read AsyncRegistration table
+ Cursor asyncRegistrationCursor =
+ readerDB.query(
+ MeasurementTables.AsyncRegistrationContract.TABLE,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null);
+ while (asyncRegistrationCursor.moveToNext()) {
+ mAsyncRegistrationList.add(
+ SqliteObjectMapper.constructAsyncRegistration(asyncRegistrationCursor));
+ }
+ asyncRegistrationCursor.close();
}
public void sortAll() {
@@ -271,6 +300,8 @@ public class DbState {
.thenComparing(AggregateReport::getSourceRegistrationTime));
mDebugReportList.sort(Comparator.comparing(DebugReport::getId));
+
+ mAsyncRegistrationList.sort(Comparator.comparing(AsyncRegistration::getRequestTime));
}
public List<AggregateEncryptionKey> getAggregateEncryptionKeyList() {
@@ -475,6 +506,28 @@ public class DbState {
.build();
}
+ private AsyncRegistration getAsyncRegistrationFrom(JSONObject aJSON) throws JSONException {
+ return new AsyncRegistration.Builder()
+ .setRegistrationId(aJSON.getString("registrationId"))
+ .setRegistrationUri(Uri.parse(aJSON.getString("registrationUri")))
+ .setTopOrigin(Uri.parse(aJSON.getString("topOrigin")))
+ .setRegistrant(Uri.parse(aJSON.getString("registrant")))
+ .setOsDestination(Uri.parse(aJSON.getString("osDestination")))
+ .setRequestTime(aJSON.getLong("requestTime"))
+ .setAdIdPermission(aJSON.getBoolean("adIdPermission"))
+ .setId(aJSON.getString("id"))
+ .setType(
+ AsyncRegistration.RegistrationType.values()[
+ aJSON.getInt("registrationType")])
+ .setPlatformAdId(aJSON.getString("platformAdId"))
+ .setDebugKeyAllowed(aJSON.getBoolean("debugKeyAllowed"))
+ .setRetryCount(aJSON.getInt("retryCount"))
+ .setVerifiedDestination(Uri.parse(aJSON.getString("verifiedDestination")))
+ .setWebDestination(Uri.parse(aJSON.getString("webDestination")))
+ .setSourceType(Source.SourceType.values()[aJSON.getInt("sourceType")])
+ .build();
+ }
+
private Uri getRegistrationOrigin(JSONObject json) throws JSONException {
return Uri.parse(
json.isNull("registration_origin")
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 4ac1b9105c..ca10c906c6 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
@@ -5975,7 +5975,7 @@ public class MeasurementDaoTest {
}
@Test
- public void testDeleteAsyncRegistrationsProvidedRegistrant() {
+ public void deleteAsyncRegistrations_success() {
SQLiteDatabase db = MeasurementDbHelper.getInstance(sContext).safeGetWritableDatabase();
AsyncRegistration ar1 =
new AsyncRegistration.Builder()
@@ -6032,12 +6032,8 @@ public class MeasurementDaoTest {
DatastoreManagerFactory.getDatastoreManager(sContext)
.runInTransaction(
- (dao) -> {
- dao.deleteAsyncRegistrationsProvidedRegistrant(
- "android-app://installed-registrant1");
- dao.deleteAsyncRegistrationsProvidedRegistrant(
- "android-app://installed-registrant2");
- });
+ (dao) ->
+ dao.deleteAsyncRegistrations(List.of("1", "3")));
assertThat(
db.query(
@@ -6060,7 +6056,7 @@ public class MeasurementDaoTest {
/* selection */ MeasurementTables.AsyncRegistrationContract
.ID
+ " = ? ",
- /* selectionArgs */ new String[] {"3"},
+ /* selectionArgs */ new String[] {"2"},
/* groupBy */ null,
/* having */ null,
/* orderedBy */ null)
@@ -6800,7 +6796,7 @@ public class MeasurementDaoTest {
// --- DELETE behaviour ---
// Delete Nothing
// No Matches
- List<String> actualSources =
+ List<String> actualTriggers =
dao.fetchMatchingTriggers(
Uri.parse("android-app://com.registrant1"),
Instant.ofEpochMilli(0),
@@ -6808,11 +6804,11 @@ public class MeasurementDaoTest {
List.of(),
List.of(),
DeletionRequest.MATCH_BEHAVIOR_DELETE);
- assertEquals(0, actualSources.size());
+ assertEquals(0, actualTriggers.size());
- // 1 & 2 match registrant1 and "https://subdomain1.site1.test" publisher
- // origin
- actualSources =
+ // 1 & 2 match registrant1 and "https://subdomain1.site1.test"
+ // destination origin
+ actualTriggers =
dao.fetchMatchingTriggers(
Uri.parse("android-app://com.registrant1"),
Instant.ofEpochMilli(0),
@@ -6822,12 +6818,11 @@ public class MeasurementDaoTest {
"https://subdomain1.site1.test")),
List.of(),
DeletionRequest.MATCH_BEHAVIOR_DELETE);
- assertEquals(2, actualSources.size());
+ assertEquals(2, actualTriggers.size());
// Only 2 matches registrant1 and "https://subdomain1.site1.test"
- // publisher origin within
- // the range
- actualSources =
+ // destination origin within the range
+ actualTriggers =
dao.fetchMatchingTriggers(
Uri.parse("android-app://com.registrant1"),
Instant.ofEpochMilli(8000),
@@ -6837,10 +6832,11 @@ public class MeasurementDaoTest {
"https://subdomain1.site1.test")),
List.of(),
DeletionRequest.MATCH_BEHAVIOR_DELETE);
- assertEquals(1, actualSources.size());
+ assertEquals(1, actualTriggers.size());
- // 1,2 & 3 matches registrant1 and "https://site1.test" publisher origin
- actualSources =
+ // 1,2 & 3 matches registrant1 and "https://site1.test" destination
+ // origin
+ actualTriggers =
dao.fetchMatchingTriggers(
Uri.parse("android-app://com.registrant1"),
Instant.ofEpochMilli(0),
@@ -6848,10 +6844,10 @@ public class MeasurementDaoTest {
List.of(),
List.of(WebUtil.validUri("https://site1.test")),
DeletionRequest.MATCH_BEHAVIOR_DELETE);
- assertEquals(3, actualSources.size());
+ assertEquals(3, actualTriggers.size());
// 3 matches origin and 4 matches domain URI
- actualSources =
+ actualTriggers =
dao.fetchMatchingTriggers(
Uri.parse("android-app://com.registrant1"),
Instant.ofEpochMilli(10000),
@@ -6861,12 +6857,12 @@ public class MeasurementDaoTest {
"https://subdomain2.site1.test")),
List.of(WebUtil.validUri("https://site2.test")),
DeletionRequest.MATCH_BEHAVIOR_DELETE);
- assertEquals(2, actualSources.size());
+ assertEquals(2, actualTriggers.size());
// --- PRESERVE (anti-match exception registrant) behaviour ---
// Preserve Nothing
// 1,2,3 & 4 are match registrant1
- actualSources =
+ actualTriggers =
dao.fetchMatchingTriggers(
Uri.parse("android-app://com.registrant1"),
Instant.ofEpochMilli(0),
@@ -6874,11 +6870,11 @@ public class MeasurementDaoTest {
List.of(),
List.of(),
DeletionRequest.MATCH_BEHAVIOR_PRESERVE);
- assertEquals(4, actualSources.size());
+ assertEquals(4, actualTriggers.size());
// 3 & 4 match registrant1 and don't match
- // "https://subdomain1.site1.test" publisher origin
- actualSources =
+ // "https://subdomain1.site1.test" destination origin
+ actualTriggers =
dao.fetchMatchingTriggers(
Uri.parse("android-app://com.registrant1"),
Instant.ofEpochMilli(0),
@@ -6888,11 +6884,11 @@ public class MeasurementDaoTest {
"https://subdomain1.site1.test")),
List.of(),
DeletionRequest.MATCH_BEHAVIOR_PRESERVE);
- assertEquals(2, actualSources.size());
+ assertEquals(2, actualTriggers.size());
// 3 & 4 match registrant1, in range and don't match
// "https://subdomain1.site1.test"
- actualSources =
+ actualTriggers =
dao.fetchMatchingTriggers(
Uri.parse("android-app://com.registrant1"),
Instant.ofEpochMilli(8000),
@@ -6902,11 +6898,11 @@ public class MeasurementDaoTest {
"https://subdomain1.site1.test")),
List.of(),
DeletionRequest.MATCH_BEHAVIOR_PRESERVE);
- assertEquals(2, actualSources.size());
+ assertEquals(2, actualTriggers.size());
// Only 4 matches registrant1, in range and don't match
// "https://site1.test"
- actualSources =
+ actualTriggers =
dao.fetchMatchingTriggers(
Uri.parse("android-app://com.registrant1"),
Instant.ofEpochMilli(0),
@@ -6914,11 +6910,11 @@ public class MeasurementDaoTest {
List.of(),
List.of(WebUtil.validUri("https://site1.test")),
DeletionRequest.MATCH_BEHAVIOR_PRESERVE);
- assertEquals(1, actualSources.size());
+ assertEquals(1, actualTriggers.size());
// only 2 is registrant1 based, in range and does not match either
// site2.test or subdomain2.site1.test
- actualSources =
+ actualTriggers =
dao.fetchMatchingTriggers(
Uri.parse("android-app://com.registrant1"),
Instant.ofEpochMilli(10000),
@@ -6928,7 +6924,210 @@ public class MeasurementDaoTest {
"https://subdomain2.site1.test")),
List.of(WebUtil.validUri("https://site2.test")),
DeletionRequest.MATCH_BEHAVIOR_PRESERVE);
- assertEquals(1, actualSources.size());
+ assertEquals(1, actualTriggers.size());
+ });
+ }
+
+ @Test
+ public void fetchMatchingAsyncRegistrations_bringsMatchingAsyncRegistrations() {
+ // Setup
+ AsyncRegistration asyncRegistration1 =
+ AsyncRegistrationFixture.getValidAsyncRegistrationBuilder()
+ .setTopOrigin(
+ WebUtil.validUri("https://subdomain1.site1.test"))
+ .setRequestTime(5000)
+ .setRegistrant(Uri.parse("android-app://com.registrant1"))
+ .setId("asyncRegistration1")
+ .build();
+ AsyncRegistration asyncRegistration2 =
+ AsyncRegistrationFixture.getValidAsyncRegistrationBuilder()
+ .setTopOrigin(
+ WebUtil.validUri("https://subdomain1.site1.test"))
+ .setRequestTime(10000)
+ .setRegistrant(Uri.parse("android-app://com.registrant1"))
+ .setId("asyncRegistration2")
+ .build();
+ AsyncRegistration asyncRegistration3 =
+ AsyncRegistrationFixture.getValidAsyncRegistrationBuilder()
+ .setTopOrigin(
+ WebUtil.validUri("https://subdomain2.site1.test"))
+ .setRequestTime(15000)
+ .setRegistrant(Uri.parse("android-app://com.registrant1"))
+ .setId("asyncRegistration3")
+ .build();
+ AsyncRegistration asyncRegistration4 =
+ AsyncRegistrationFixture.getValidAsyncRegistrationBuilder()
+ .setTopOrigin(
+ WebUtil.validUri("https://subdomain2.site2.test"))
+ .setRequestTime(15000)
+ .setRegistrant(Uri.parse("android-app://com.registrant1"))
+ .setId("asyncRegistration4")
+ .build();
+ AsyncRegistration asyncRegistration5 =
+ AsyncRegistrationFixture.getValidAsyncRegistrationBuilder()
+ .setTopOrigin(
+ WebUtil.validUri("https://subdomain2.site1.test"))
+ .setRequestTime(20000)
+ .setRegistrant(Uri.parse("android-app://com.registrant2"))
+ .setId("asyncRegistration5")
+ .build();
+ List<AsyncRegistration> asyncRegistrations = List.of(
+ asyncRegistration1, asyncRegistration2, asyncRegistration3, asyncRegistration4,
+ asyncRegistration5);
+
+ SQLiteDatabase db = MeasurementDbHelper.getInstance(sContext).getWritableDatabase();
+ asyncRegistrations.forEach(
+ asyncRegistration -> {
+ ContentValues values = new ContentValues();
+ values.put(AsyncRegistrationContract.ID, asyncRegistration.getId());
+ values.put(
+ AsyncRegistrationContract.TOP_ORIGIN,
+ asyncRegistration.getTopOrigin().toString());
+ values.put(AsyncRegistrationContract.REQUEST_TIME,
+ asyncRegistration.getRequestTime());
+ values.put(AsyncRegistrationContract.REGISTRANT,
+ asyncRegistration.getRegistrant().toString());
+ values.put(AsyncRegistrationContract.REGISTRATION_ID,
+ UUID.randomUUID().toString());
+ db.insert(AsyncRegistrationContract.TABLE, /* nullColumnHack */ null, values);
+ });
+
+ // Execution
+ DatastoreManagerFactory.getDatastoreManager(sContext)
+ .runInTransaction(
+ dao -> {
+ // --- DELETE behaviour ---
+ // Delete Nothing
+ // No Matches
+ List<String> actualAsyncRegistrations =
+ dao.fetchMatchingAsyncRegistrations(
+ Uri.parse("android-app://com.registrant1"),
+ Instant.ofEpochMilli(0),
+ Instant.ofEpochMilli(50000),
+ List.of(),
+ List.of(),
+ DeletionRequest.MATCH_BEHAVIOR_DELETE);
+ assertEquals(0, actualAsyncRegistrations.size());
+
+ // 1 & 2 match registrant1 and "https://subdomain1.site1.test" top-
+ // origin origin
+ actualAsyncRegistrations =
+ dao.fetchMatchingAsyncRegistrations(
+ Uri.parse("android-app://com.registrant1"),
+ Instant.ofEpochMilli(0),
+ Instant.ofEpochMilli(50000),
+ List.of(
+ WebUtil.validUri(
+ "https://subdomain1.site1.test")),
+ List.of(),
+ DeletionRequest.MATCH_BEHAVIOR_DELETE);
+ assertEquals(2, actualAsyncRegistrations.size());
+
+ // Only 2 matches registrant1 and "https://subdomain1.site1.test"
+ // top-origin origin within the range
+ actualAsyncRegistrations =
+ dao.fetchMatchingAsyncRegistrations(
+ Uri.parse("android-app://com.registrant1"),
+ Instant.ofEpochMilli(8000),
+ Instant.ofEpochMilli(50000),
+ List.of(
+ WebUtil.validUri(
+ "https://subdomain1.site1.test")),
+ List.of(),
+ DeletionRequest.MATCH_BEHAVIOR_DELETE);
+ assertEquals(1, actualAsyncRegistrations.size());
+
+ // 1,2 & 3 matches registrant1 and "https://site1.test" top-origin
+ // origin
+ actualAsyncRegistrations =
+ dao.fetchMatchingAsyncRegistrations(
+ Uri.parse("android-app://com.registrant1"),
+ Instant.ofEpochMilli(0),
+ Instant.ofEpochMilli(50000),
+ List.of(),
+ List.of(WebUtil.validUri("https://site1.test")),
+ DeletionRequest.MATCH_BEHAVIOR_DELETE);
+ assertEquals(3, actualAsyncRegistrations.size());
+
+ // 3 matches origin and 4 matches domain URI
+ actualAsyncRegistrations =
+ dao.fetchMatchingAsyncRegistrations(
+ Uri.parse("android-app://com.registrant1"),
+ Instant.ofEpochMilli(10000),
+ Instant.ofEpochMilli(20000),
+ List.of(
+ WebUtil.validUri(
+ "https://subdomain2.site1.test")),
+ List.of(WebUtil.validUri("https://site2.test")),
+ DeletionRequest.MATCH_BEHAVIOR_DELETE);
+ assertEquals(2, actualAsyncRegistrations.size());
+
+ // --- PRESERVE (anti-match exception registrant) behaviour ---
+ // Preserve Nothing
+ // 1,2,3 & 4 are match registrant1
+ actualAsyncRegistrations =
+ dao.fetchMatchingAsyncRegistrations(
+ Uri.parse("android-app://com.registrant1"),
+ Instant.ofEpochMilli(0),
+ Instant.ofEpochMilli(50000),
+ List.of(),
+ List.of(),
+ DeletionRequest.MATCH_BEHAVIOR_PRESERVE);
+ assertEquals(4, actualAsyncRegistrations.size());
+
+ // 3 & 4 match registrant1 and don't match
+ // "https://subdomain1.site1.test" top-origin origin
+ actualAsyncRegistrations =
+ dao.fetchMatchingAsyncRegistrations(
+ Uri.parse("android-app://com.registrant1"),
+ Instant.ofEpochMilli(0),
+ Instant.ofEpochMilli(50000),
+ List.of(
+ WebUtil.validUri(
+ "https://subdomain1.site1.test")),
+ List.of(),
+ DeletionRequest.MATCH_BEHAVIOR_PRESERVE);
+ assertEquals(2, actualAsyncRegistrations.size());
+
+ // 3 & 4 match registrant1, in range and don't match
+ // "https://subdomain1.site1.test"
+ actualAsyncRegistrations =
+ dao.fetchMatchingAsyncRegistrations(
+ Uri.parse("android-app://com.registrant1"),
+ Instant.ofEpochMilli(8000),
+ Instant.ofEpochMilli(50000),
+ List.of(
+ WebUtil.validUri(
+ "https://subdomain1.site1.test")),
+ List.of(),
+ DeletionRequest.MATCH_BEHAVIOR_PRESERVE);
+ assertEquals(2, actualAsyncRegistrations.size());
+
+ // Only 4 matches registrant1, in range and don't match
+ // "https://site1.test"
+ actualAsyncRegistrations =
+ dao.fetchMatchingAsyncRegistrations(
+ Uri.parse("android-app://com.registrant1"),
+ Instant.ofEpochMilli(0),
+ Instant.ofEpochMilli(50000),
+ List.of(),
+ List.of(WebUtil.validUri("https://site1.test")),
+ DeletionRequest.MATCH_BEHAVIOR_PRESERVE);
+ assertEquals(1, actualAsyncRegistrations.size());
+
+ // only 2 is registrant1 based, in range and does not match either
+ // site2.test or subdomain2.site1.test
+ actualAsyncRegistrations =
+ dao.fetchMatchingAsyncRegistrations(
+ Uri.parse("android-app://com.registrant1"),
+ Instant.ofEpochMilli(10000),
+ Instant.ofEpochMilli(20000),
+ List.of(
+ WebUtil.validUri(
+ "https://subdomain2.site1.test")),
+ List.of(WebUtil.validUri("https://site2.test")),
+ DeletionRequest.MATCH_BEHAVIOR_PRESERVE);
+ assertEquals(1, actualAsyncRegistrations.size());
});
}
diff --git a/adservices/tests/unittest/service-core/src/com/android/adservices/data/measurement/deletion/MeasurementDataDeleterTest.java b/adservices/tests/unittest/service-core/src/com/android/adservices/data/measurement/deletion/MeasurementDataDeleterTest.java
index 66bc109204..d16cfb9d0b 100644
--- a/adservices/tests/unittest/service-core/src/com/android/adservices/data/measurement/deletion/MeasurementDataDeleterTest.java
+++ b/adservices/tests/unittest/service-core/src/com/android/adservices/data/measurement/deletion/MeasurementDataDeleterTest.java
@@ -383,6 +383,7 @@ public class MeasurementDataDeleterTest {
MeasurementDataDeleter subjectUnderTest = spy(mMeasurementDataDeleter);
List<String> triggerIds = List.of("triggerId1", "triggerId2");
List<String> sourceIds = List.of("sourceId1", "sourceId2");
+ List<String> asyncRegistrationIds = List.of("asyncRegId1", "asyncRegId2");
Source source1 = SourceFixture.getMinimalValidSourceBuilder().setId("sourceId1").build();
Source source2 =
SourceFixture.getMinimalValidSourceBuilder()
@@ -428,6 +429,14 @@ public class MeasurementDataDeleterTest {
mDomainUris,
DeletionRequest.MATCH_BEHAVIOR_DELETE))
.thenReturn(Arrays.asList(source1.getId(), source2.getId()));
+ when(mMeasurementDao.fetchMatchingAsyncRegistrations(
+ Uri.parse(ANDROID_APP_SCHEME + "://" + APP_PACKAGE_NAME),
+ START,
+ END,
+ mOriginUris,
+ mDomainUris,
+ DeletionRequest.MATCH_BEHAVIOR_DELETE))
+ .thenReturn(asyncRegistrationIds);
when(mMeasurementDao.fetchMatchingTriggers(
Uri.parse(ANDROID_APP_SCHEME + "://" + APP_PACKAGE_NAME),
START,
@@ -451,9 +460,9 @@ public class MeasurementDataDeleterTest {
mMeasurementDao, List.of(mAggregateReport1, mAggregateReport2));
verify(subjectUnderTest)
.resetDedupKeys(mMeasurementDao, List.of(mEventReport1, mEventReport2));
+ verify(mMeasurementDao).deleteAsyncRegistrations(asyncRegistrationIds);
verify(mMeasurementDao).deleteSources(sourceIds);
verify(mMeasurementDao).deleteTriggers(triggerIds);
- verify(mMeasurementDao).deleteAsyncRegistrationsProvidedRegistrant(APP_PACKAGE_NAME);
verify(subjectUnderTest)
.resetAggregateReportDedupKeys(
mMeasurementDao, List.of(mAggregateReport1, mAggregateReport2));