diff options
author | Gilad Barkan <giladbarkan@google.com> | 2023-07-12 21:56:52 +0000 |
---|---|---|
committer | Gilad Barkan <giladbarkan@google.com> | 2023-07-13 00:11:50 +0000 |
commit | eab6f64aad5c7173c15f1c9d6fd197b0f291a0c3 (patch) | |
tree | cce471b34e1cf9f21b979602c4b55fd55f3de2ed | |
parent | 86eefbc8679c45a1731177ad0627b3a0c56c8d8c (diff) | |
download | AdServices-eab6f64aad5c7173c15f1c9d6fd197b0f291a0c3.tar.gz |
Measurement deletion of async registration records
Bug: 281699821
Bug: 290984420
Test: atest com.android.adservices.data.measurement
Change-Id: I3e2b31b5625f8a34047b768b8d8cb1ac802a02a6
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)); |