• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.adservices.data.measurement;
18 
19 import static java.util.function.Predicate.not;
20 
21 import android.database.Cursor;
22 import android.net.Uri;
23 
24 import com.android.adservices.data.measurement.MeasurementTables.SourceContract;
25 import com.android.adservices.service.measurement.CountUniqueMetadata;
26 import com.android.adservices.service.measurement.CountUniqueReport;
27 import com.android.adservices.service.measurement.EventReport;
28 import com.android.adservices.service.measurement.Source;
29 import com.android.adservices.service.measurement.Trigger;
30 import com.android.adservices.service.measurement.aggregation.AggregateEncryptionKey;
31 import com.android.adservices.service.measurement.aggregation.AggregateReport;
32 import com.android.adservices.service.measurement.registration.AsyncRedirect;
33 import com.android.adservices.service.measurement.registration.AsyncRegistration;
34 import com.android.adservices.service.measurement.reporting.DebugReport;
35 import com.android.adservices.service.measurement.util.UnsignedLong;
36 
37 import java.util.Arrays;
38 import java.util.List;
39 import java.util.Set;
40 import java.util.function.Function;
41 import java.util.stream.Collectors;
42 import java.util.stream.Stream;
43 
44 /** Helper class for SQLite operations. */
45 public class SqliteObjectMapper {
46     /**
47      * Create {@link EventReport} object from SQLite datastore.
48      */
constructEventReportFromCursor(Cursor cursor)49     static EventReport constructEventReportFromCursor(Cursor cursor) {
50         EventReport.Builder builder = new EventReport.Builder();
51         setTextColumn(cursor, MeasurementTables.EventReportContract.ID,
52                 builder::setId);
53         setUnsignedLongColumn(
54                 cursor,
55                 MeasurementTables.EventReportContract.SOURCE_EVENT_ID,
56                 builder::setSourceEventId);
57         setLongColumn(cursor, MeasurementTables.EventReportContract.TRIGGER_PRIORITY,
58                 builder::setTriggerPriority);
59         setIntColumn(cursor, MeasurementTables.EventReportContract.STATUS,
60                 builder::setStatus);
61         setIntColumn(
62                 cursor,
63                 MeasurementTables.EventReportContract.DEBUG_REPORT_STATUS,
64                 builder::setDebugReportStatus);
65         setUnsignedLongColumn(cursor, MeasurementTables.EventReportContract.TRIGGER_DATA,
66                 builder::setTriggerData);
67         setUnsignedLongColumn(cursor, MeasurementTables.EventReportContract.TRIGGER_DEDUP_KEY,
68                 builder::setTriggerDedupKey);
69         setTextColumn(
70                 cursor,
71                 MeasurementTables.EventReportContract.ATTRIBUTION_DESTINATION,
72                 (destinations) ->
73                         builder.setAttributionDestinations(destinationsStringToList(destinations)));
74         setTextColumn(cursor, MeasurementTables.EventReportContract.ENROLLMENT_ID,
75                 builder::setEnrollmentId);
76         setLongColumn(cursor, MeasurementTables.EventReportContract.REPORT_TIME,
77                 builder::setReportTime);
78         setLongColumn(cursor, MeasurementTables.EventReportContract.TRIGGER_TIME,
79                 builder::setTriggerTime);
80         setTextColumn(cursor, MeasurementTables.EventReportContract.SOURCE_TYPE,
81                 (enumValue) -> builder.setSourceType(Source.SourceType.valueOf(enumValue)));
82         setDoubleColumn(cursor, MeasurementTables.EventReportContract.RANDOMIZED_TRIGGER_RATE,
83                 builder::setRandomizedTriggerRate);
84         setUnsignedLongColumn(
85                 cursor,
86                 MeasurementTables.EventReportContract.SOURCE_DEBUG_KEY,
87                 builder::setSourceDebugKey);
88         setUnsignedLongColumn(
89                 cursor,
90                 MeasurementTables.EventReportContract.TRIGGER_DEBUG_KEY,
91                 builder::setTriggerDebugKey);
92         setTextColumn(
93                 cursor,
94                 MeasurementTables.EventReportContract.TRIGGER_DEBUG_KEYS,
95                 (concatArray) ->
96                         builder.setTriggerDebugKeys(unsignedLongsStringToList(concatArray)));
97         setTextColumn(
98                 cursor, MeasurementTables.EventReportContract.SOURCE_ID, builder::setSourceId);
99         setTextColumn(
100                 cursor, MeasurementTables.EventReportContract.TRIGGER_ID, builder::setTriggerId);
101         setTextColumn(
102                 cursor,
103                 MeasurementTables.EventReportContract.REGISTRATION_ORIGIN,
104                 registration_origin ->
105                         builder.setRegistrationOrigin(Uri.parse(registration_origin)));
106         setTextColumn(
107                 cursor,
108                 MeasurementTables.EventReportContract.TRIGGER_SUMMARY_BUCKET,
109                 builder::setTriggerSummaryBucket);
110         return builder.build();
111     }
112 
113     /** Create {@link Source} object from SQLite datastore. */
constructSourceFromCursor(Cursor cursor)114     static Source constructSourceFromCursor(Cursor cursor) {
115         Source.Builder builder = new Source.Builder();
116         setTextColumn(cursor, MeasurementTables.SourceContract.ID,
117                 builder::setId);
118         setUnsignedLongColumn(cursor, MeasurementTables.SourceContract.EVENT_ID,
119                 builder::setEventId);
120         setLongColumn(cursor, MeasurementTables.SourceContract.PRIORITY,
121                 builder::setPriority);
122         setTextColumn(cursor, MeasurementTables.SourceContract.ENROLLMENT_ID,
123                 builder::setEnrollmentId);
124         setUriColumn(cursor, MeasurementTables.SourceContract.PUBLISHER,
125                 builder::setPublisher);
126         setIntColumn(cursor, MeasurementTables.SourceContract.PUBLISHER_TYPE,
127                 builder::setPublisherType);
128         setTextColumn(cursor, MeasurementTables.SourceContract.SOURCE_TYPE,
129                 (enumValue) -> builder.setSourceType(Source.SourceType.valueOf(enumValue)));
130         setLongColumn(cursor, MeasurementTables.SourceContract.EXPIRY_TIME,
131                 builder::setExpiryTime);
132         setLongColumn(cursor, MeasurementTables.SourceContract.EVENT_REPORT_WINDOW,
133                 builder::setEventReportWindow);
134         setLongColumn(cursor, MeasurementTables.SourceContract.AGGREGATABLE_REPORT_WINDOW,
135                 builder::setAggregatableReportWindow);
136         setLongColumn(cursor, MeasurementTables.SourceContract.EVENT_TIME,
137                 builder::setEventTime);
138         setTextColumn(
139                 cursor,
140                 MeasurementTables.SourceContract.EVENT_REPORT_DEDUP_KEYS,
141                 (concatArray) ->
142                         builder.setEventReportDedupKeys(unsignedLongsStringToList(concatArray)));
143         setTextColumn(
144                 cursor,
145                 MeasurementTables.SourceContract.AGGREGATE_REPORT_DEDUP_KEYS,
146                 (concatArray) ->
147                         builder.setAggregateReportDedupKeys(
148                                 unsignedLongsStringToList(concatArray)));
149         setIntColumn(cursor, MeasurementTables.SourceContract.STATUS,
150                 builder::setStatus);
151         setUriColumn(cursor, MeasurementTables.SourceContract.REGISTRANT,
152                 builder::setRegistrant);
153         setIntColumn(cursor, MeasurementTables.SourceContract.ATTRIBUTION_MODE,
154                 builder::setAttributionMode);
155         setLongColumn(cursor, MeasurementTables.SourceContract.INSTALL_ATTRIBUTION_WINDOW,
156                 builder::setInstallAttributionWindow);
157         setLongColumn(cursor, MeasurementTables.SourceContract.INSTALL_COOLDOWN_WINDOW,
158                 builder::setInstallCooldownWindow);
159         setBooleanColumn(cursor, MeasurementTables.SourceContract.IS_INSTALL_ATTRIBUTED,
160                 builder::setInstallAttributed);
161         setLongColumn(
162                 cursor,
163                 MeasurementTables.SourceContract.REINSTALL_REATTRIBUTION_WINDOW,
164                 builder::setReinstallReattributionWindow);
165         setTextColumn(cursor, MeasurementTables.SourceContract.FILTER_DATA,
166                 builder::setFilterDataString);
167         setTextColumn(cursor, MeasurementTables.SourceContract.AGGREGATE_SOURCE,
168                 builder::setAggregateSource);
169         setIntColumn(cursor, MeasurementTables.SourceContract.AGGREGATE_CONTRIBUTIONS,
170                 builder::setAggregateContributions);
171         setUnsignedLongColumn(cursor, MeasurementTables.SourceContract.DEBUG_KEY,
172                 builder::setDebugKey);
173         setBooleanColumn(
174                 cursor,
175                 MeasurementTables.SourceContract.DEBUG_REPORTING,
176                 builder::setIsDebugReporting);
177         setBooleanColumn(
178                 cursor,
179                 MeasurementTables.SourceContract.AD_ID_PERMISSION,
180                 builder::setAdIdPermission);
181         setBooleanColumn(
182                 cursor,
183                 MeasurementTables.SourceContract.AR_DEBUG_PERMISSION,
184                 builder::setArDebugPermission);
185         setTextColumn(
186                 cursor,
187                 MeasurementTables.SourceContract.SHARED_AGGREGATION_KEYS,
188                 builder::setSharedAggregationKeys);
189         setTextColumn(
190                 cursor,
191                 MeasurementTables.SourceContract.REGISTRATION_ID,
192                 builder::setRegistrationId);
193         setTextColumn(
194                 cursor, MeasurementTables.SourceContract.DEBUG_JOIN_KEY, builder::setDebugJoinKey);
195         setLongColumn(
196                 cursor, MeasurementTables.SourceContract.INSTALL_TIME, builder::setInstallTime);
197         setTextColumn(
198                 cursor, MeasurementTables.SourceContract.PLATFORM_AD_ID, builder::setPlatformAdId);
199         setTextColumn(cursor, MeasurementTables.SourceContract.DEBUG_AD_ID, builder::setDebugAdId);
200         setUriColumn(
201                 cursor,
202                 MeasurementTables.SourceContract.REGISTRATION_ORIGIN,
203                 builder::setRegistrationOrigin);
204         setBooleanColumn(
205                 cursor,
206                 MeasurementTables.SourceContract.COARSE_EVENT_REPORT_DESTINATIONS,
207                 builder::setCoarseEventReportDestinations);
208         setTextColumn(
209                 cursor,
210                 MeasurementTables.SourceContract.TRIGGER_DATA,
211                 (concatArray) ->
212                         builder.setTriggerData(unsignedLongsStringToSet(concatArray)));
213         setTextColumn(
214                 cursor,
215                 MeasurementTables.SourceContract.TRIGGER_SPECS,
216                 builder::setTriggerSpecsString);
217         setIntColumn(
218                 cursor,
219                 MeasurementTables.SourceContract.MAX_EVENT_LEVEL_REPORTS,
220                 builder::setMaxEventLevelReports);
221         setTextColumn(
222                 cursor,
223                 MeasurementTables.SourceContract.EVENT_ATTRIBUTION_STATUS,
224                 builder::setEventAttributionStatus);
225         setTextColumn(
226                 cursor,
227                 MeasurementTables.SourceContract.PRIVACY_PARAMETERS,
228                 builder::setPrivacyParameters);
229         setTextColumn(
230                 cursor,
231                 MeasurementTables.SourceContract.EVENT_REPORT_WINDOWS,
232                 builder::setEventReportWindows);
233         setUnsignedLongColumn(
234                 cursor,
235                 MeasurementTables.SourceContract.SHARED_DEBUG_KEY,
236                 builder::setSharedDebugKey);
237         setTextColumn(
238                 cursor,
239                 MeasurementTables.SourceContract.SHARED_FILTER_DATA_KEYS,
240                 builder::setSharedFilterDataKeys);
241         setTextColumn(cursor, MeasurementTables.SourceContract.TRIGGER_DATA_MATCHING,
242                 (enumValue) -> builder.setTriggerDataMatching(
243                         Source.TriggerDataMatching.valueOf(enumValue)));
244         setLongColumn(
245                 cursor,
246                 MeasurementTables.SourceContract.ATTRIBUTION_SCOPE_LIMIT,
247                 builder::setAttributionScopeLimit);
248         setLongColumn(
249                 cursor,
250                 MeasurementTables.SourceContract.MAX_EVENT_STATES,
251                 builder::setMaxEventStates);
252         setLongColumn(
253                 cursor,
254                 MeasurementTables.SourceContract.DESTINATION_LIMIT_PRIORITY,
255                 builder::setDestinationLimitPriority);
256         setDoubleColumn(
257                 cursor,
258                 MeasurementTables.SourceContract.EVENT_LEVEL_EPSILON,
259                 builder::setEventLevelEpsilon);
260         setTextColumn(
261                 cursor,
262                 MeasurementTables.SourceContract.AGGREGATE_DEBUG_REPORTING,
263                 builder::setAggregateDebugReportingString);
264         setIntColumn(
265                 cursor,
266                 SourceContract.AGGREGATE_DEBUG_REPORT_CONTRIBUTIONS,
267                 builder::setAggregateDebugReportContributions);
268 
269         return builder.build();
270     }
271 
272     /** Create {@link Trigger} object from SQLite datastore. */
constructTriggerFromCursor(Cursor cursor)273     public static Trigger constructTriggerFromCursor(Cursor cursor) {
274         Trigger.Builder builder = new Trigger.Builder();
275         setTextColumn(cursor, MeasurementTables.TriggerContract.ID,
276                 builder::setId);
277         setTextColumn(
278                 cursor,
279                 MeasurementTables.TriggerContract.EVENT_TRIGGERS,
280                 builder::setEventTriggers);
281         setUriColumn(cursor, MeasurementTables.TriggerContract.ATTRIBUTION_DESTINATION,
282                 builder::setAttributionDestination);
283         setIntColumn(cursor, MeasurementTables.TriggerContract.DESTINATION_TYPE,
284                 builder::setDestinationType);
285         setTextColumn(cursor, MeasurementTables.TriggerContract.ENROLLMENT_ID,
286                 builder::setEnrollmentId);
287         setIntColumn(cursor, MeasurementTables.TriggerContract.STATUS,
288                 builder::setStatus);
289         setLongColumn(cursor, MeasurementTables.TriggerContract.TRIGGER_TIME,
290                 builder::setTriggerTime);
291         setUriColumn(cursor, MeasurementTables.TriggerContract.REGISTRANT,
292                 builder::setRegistrant);
293         setTextColumn(cursor, MeasurementTables.TriggerContract.AGGREGATE_TRIGGER_DATA,
294                 builder::setAggregateTriggerData);
295         setTextColumn(
296                 cursor,
297                 MeasurementTables.TriggerContract.AGGREGATE_VALUES,
298                 builder::setAggregateValuesString);
299         setTextColumn(
300                 cursor,
301                 MeasurementTables.TriggerContract.AGGREGATABLE_DEDUPLICATION_KEYS,
302                 builder::setAggregateDeduplicationKeys);
303         setTextColumn(cursor, MeasurementTables.TriggerContract.FILTERS, builder::setFilters);
304         setTextColumn(cursor, MeasurementTables.TriggerContract.NOT_FILTERS,
305                 builder::setNotFilters);
306         setUnsignedLongColumn(cursor, MeasurementTables.TriggerContract.DEBUG_KEY,
307                 builder::setDebugKey);
308         setBooleanColumn(
309                 cursor,
310                 MeasurementTables.TriggerContract.DEBUG_REPORTING,
311                 builder::setIsDebugReporting);
312         setBooleanColumn(
313                 cursor,
314                 MeasurementTables.TriggerContract.AD_ID_PERMISSION,
315                 builder::setAdIdPermission);
316         setBooleanColumn(
317                 cursor,
318                 MeasurementTables.TriggerContract.AR_DEBUG_PERMISSION,
319                 builder::setArDebugPermission);
320         setTextColumn(
321                 cursor,
322                 MeasurementTables.TriggerContract.ATTRIBUTION_CONFIG,
323                 builder::setAttributionConfig);
324         setTextColumn(
325                 cursor,
326                 MeasurementTables.TriggerContract.X_NETWORK_KEY_MAPPING,
327                 builder::setAdtechBitMapping);
328         setTextColumn(
329                 cursor, MeasurementTables.TriggerContract.DEBUG_JOIN_KEY, builder::setDebugJoinKey);
330         setTextColumn(
331                 cursor, MeasurementTables.TriggerContract.PLATFORM_AD_ID, builder::setPlatformAdId);
332         setTextColumn(cursor, MeasurementTables.TriggerContract.DEBUG_AD_ID, builder::setDebugAdId);
333         setTextColumn(
334                 cursor,
335                 MeasurementTables.TriggerContract.REGISTRATION_ORIGIN,
336                 registration_origin ->
337                         builder.setRegistrationOrigin(Uri.parse(registration_origin)));
338         setUriColumn(
339                 cursor,
340                 MeasurementTables.TriggerContract.AGGREGATION_COORDINATOR_ORIGIN,
341                 builder::setAggregationCoordinatorOrigin);
342         setTextColumn(
343                 cursor,
344                 MeasurementTables.TriggerContract.AGGREGATABLE_SOURCE_REGISTRATION_TIME_CONFIG,
345                 (enumValue) ->
346                         builder.setAggregatableSourceRegistrationTimeConfig(
347                                 Trigger.SourceRegistrationTimeConfig.valueOf(enumValue)));
348         setTextColumn(
349                 cursor,
350                 MeasurementTables.TriggerContract.TRIGGER_CONTEXT_ID,
351                 builder::setTriggerContextId);
352         setTextColumn(
353                 cursor,
354                 MeasurementTables.TriggerContract.ATTRIBUTION_SCOPES,
355                 builder::setAttributionScopesString);
356         setIntColumn(
357                 cursor,
358                 MeasurementTables.TriggerContract.AGGREGATABLE_FILTERING_ID_MAX_BYTES,
359                 builder::setAggregatableFilteringIdMaxBytes);
360         setTextColumn(
361                 cursor,
362                 MeasurementTables.TriggerContract.AGGREGATE_DEBUG_REPORTING,
363                 builder::setAggregateDebugReportingString);
364         setTextColumn(
365                 cursor,
366                 MeasurementTables.TriggerContract.NAMED_BUDGETS,
367                 builder::setNamedBudgetsString);
368         return builder.build();
369     }
370 
371     /**
372      * Create {@link AggregateReport} object from SQLite datastore.
373      */
constructAggregateReport(Cursor cursor)374     static AggregateReport constructAggregateReport(Cursor cursor) {
375         AggregateReport.Builder builder = new AggregateReport.Builder();
376         setTextColumn(cursor, MeasurementTables.AggregateReport.ID,
377                 builder::setId);
378         setUriColumn(cursor, MeasurementTables.AggregateReport.PUBLISHER,
379                 builder::setPublisher);
380         setUriColumn(cursor, MeasurementTables.AggregateReport.ATTRIBUTION_DESTINATION,
381                 builder::setAttributionDestination);
382         setLongColumn(
383                 cursor,
384                 MeasurementTables.AggregateReport.SOURCE_REGISTRATION_TIME,
385                 builder::setSourceRegistrationTime);
386         setLongColumn(cursor, MeasurementTables.AggregateReport.SCHEDULED_REPORT_TIME,
387                 builder::setScheduledReportTime);
388         setTextColumn(cursor, MeasurementTables.AggregateReport.ENROLLMENT_ID,
389                 builder::setEnrollmentId);
390         setTextColumn(cursor, MeasurementTables.AggregateReport.DEBUG_CLEARTEXT_PAYLOAD,
391                 builder::setDebugCleartextPayload);
392         setIntColumn(cursor, MeasurementTables.AggregateReport.STATUS,
393                 builder::setStatus);
394         setIntColumn(
395                 cursor,
396                 MeasurementTables.AggregateReport.DEBUG_REPORT_STATUS,
397                 builder::setDebugReportStatus);
398         setTextColumn(cursor, MeasurementTables.AggregateReport.API_VERSION,
399                 builder::setApiVersion);
400         setUnsignedLongColumn(
401                 cursor,
402                 MeasurementTables.AggregateReport.SOURCE_DEBUG_KEY,
403                 builder::setSourceDebugKey);
404         setUnsignedLongColumn(
405                 cursor,
406                 MeasurementTables.AggregateReport.TRIGGER_DEBUG_KEY,
407                 builder::setTriggerDebugKey);
408         setTextColumn(cursor, MeasurementTables.AggregateReport.SOURCE_ID, builder::setSourceId);
409         setTextColumn(cursor, MeasurementTables.AggregateReport.TRIGGER_ID, builder::setTriggerId);
410         setUnsignedLongColumn(
411                 cursor, MeasurementTables.AggregateReport.DEDUP_KEY, builder::setDedupKey);
412         setTextColumn(
413                 cursor,
414                 MeasurementTables.AggregateReport.REGISTRATION_ORIGIN,
415                 registration_origin ->
416                         builder.setRegistrationOrigin(Uri.parse(registration_origin)));
417         setUriColumn(
418                 cursor,
419                 MeasurementTables.AggregateReport.AGGREGATION_COORDINATOR_ORIGIN,
420                 builder::setAggregationCoordinatorOrigin);
421         setBooleanColumn(
422                 cursor, MeasurementTables.AggregateReport.IS_FAKE_REPORT, builder::setIsFakeReport);
423         setTextColumn(
424                 cursor,
425                 MeasurementTables.AggregateReport.TRIGGER_CONTEXT_ID,
426                 builder::setTriggerContextId);
427         setLongColumn(
428                 cursor, MeasurementTables.AggregateReport.TRIGGER_TIME, builder::setTriggerTime);
429         setTextColumn(cursor, MeasurementTables.AggregateReport.API, builder::setApi);
430         setIntColumn(
431                 cursor,
432                 MeasurementTables.AggregateReport.AGGREGATABLE_FILTERING_ID_MAX_BYTES,
433                 builder::setAggregatableFilteringIdMaxBytes);
434         return builder.build();
435     }
436 
437     /**
438      * Create {@link AggregateEncryptionKey} object from SQLite datastore.
439      */
constructAggregateEncryptionKeyFromCursor(Cursor cursor)440     static AggregateEncryptionKey constructAggregateEncryptionKeyFromCursor(Cursor cursor) {
441         AggregateEncryptionKey.Builder builder = new AggregateEncryptionKey.Builder();
442         setTextColumn(cursor, MeasurementTables.AggregateEncryptionKey.ID,
443                 builder::setId);
444         setTextColumn(cursor, MeasurementTables.AggregateEncryptionKey.KEY_ID,
445                 builder::setKeyId);
446         setTextColumn(cursor, MeasurementTables.AggregateEncryptionKey.PUBLIC_KEY,
447                 builder::setPublicKey);
448         setLongColumn(cursor, MeasurementTables.AggregateEncryptionKey.EXPIRY,
449                 builder::setExpiry);
450         setUriColumn(
451                 cursor,
452                 MeasurementTables.AggregateEncryptionKey.AGGREGATION_COORDINATOR_ORIGIN,
453                 builder::setAggregationCoordinatorOrigin);
454         return builder.build();
455     }
456 
457     /** Create {@link DebugReport} object from SQLite datastore. */
constructDebugReportFromCursor(Cursor cursor)458     static DebugReport constructDebugReportFromCursor(Cursor cursor) {
459         DebugReport.Builder builder = new DebugReport.Builder();
460         setTextColumn(cursor, MeasurementTables.DebugReportContract.ID, builder::setId);
461         setTextColumn(cursor, MeasurementTables.DebugReportContract.TYPE, builder::setType);
462         setTextColumn(cursor, MeasurementTables.DebugReportContract.BODY, builder::setBody);
463         setTextColumn(
464                 cursor,
465                 MeasurementTables.DebugReportContract.ENROLLMENT_ID,
466                 builder::setEnrollmentId);
467         setUriColumn(
468                 cursor,
469                 MeasurementTables.DebugReportContract.REGISTRATION_ORIGIN,
470                 builder::setRegistrationOrigin);
471         setTextColumn(
472                 cursor,
473                 MeasurementTables.DebugReportContract.REFERENCE_ID,
474                 builder::setReferenceId);
475         setLongColumn(
476                 cursor,
477                 MeasurementTables.DebugReportContract.INSERTION_TIME,
478                 builder::setInsertionTime);
479         setUriColumn(
480                 cursor, MeasurementTables.DebugReportContract.REGISTRANT, builder::setRegistrant);
481         return builder.build();
482     }
483 
484     /** Create {@link AsyncRegistration} object from SQLite datastore. */
constructAsyncRegistration(Cursor cursor)485     public static AsyncRegistration constructAsyncRegistration(Cursor cursor) {
486         AsyncRegistration.Builder builder = new AsyncRegistration.Builder();
487         setTextColumn(cursor, MeasurementTables.AsyncRegistrationContract.ID, builder::setId);
488         setUriColumn(
489                 cursor,
490                 MeasurementTables.AsyncRegistrationContract.WEB_DESTINATION,
491                 builder::setWebDestination);
492         setUriColumn(
493                 cursor,
494                 MeasurementTables.AsyncRegistrationContract.OS_DESTINATION,
495                 builder::setOsDestination);
496         setUriColumn(
497                 cursor,
498                 MeasurementTables.AsyncRegistrationContract.REGISTRATION_URI,
499                 builder::setRegistrationUri);
500         setUriColumn(
501                 cursor,
502                 MeasurementTables.AsyncRegistrationContract.VERIFIED_DESTINATION,
503                 builder::setVerifiedDestination);
504         setUriColumn(
505                 cursor,
506                 MeasurementTables.AsyncRegistrationContract.TOP_ORIGIN,
507                 builder::setTopOrigin);
508         setIntColumn(
509                 cursor,
510                 MeasurementTables.AsyncRegistrationContract.SOURCE_TYPE,
511                 (enumValue) ->
512                         builder.setSourceType(
513                                 enumValue == null ? null : Source.SourceType.values()[enumValue]));
514         setUriColumn(
515                 cursor,
516                 MeasurementTables.AsyncRegistrationContract.REGISTRANT,
517                 builder::setRegistrant);
518         setLongColumn(
519                 cursor,
520                 MeasurementTables.AsyncRegistrationContract.REQUEST_TIME,
521                 builder::setRequestTime);
522         setLongColumn(
523                 cursor,
524                 MeasurementTables.AsyncRegistrationContract.RETRY_COUNT,
525                 builder::setRetryCount);
526         setIntColumn(
527                 cursor,
528                 MeasurementTables.AsyncRegistrationContract.TYPE,
529                 (enumValue) ->
530                         builder.setType(
531                                 enumValue == null
532                                         ? null
533                                         : AsyncRegistration.RegistrationType.values()[enumValue]));
534         setBooleanColumn(
535                 cursor,
536                 MeasurementTables.AsyncRegistrationContract.DEBUG_KEY_ALLOWED,
537                 builder::setDebugKeyAllowed);
538         setBooleanColumn(
539                 cursor,
540                 MeasurementTables.AsyncRegistrationContract.AD_ID_PERMISSION,
541                 builder::setAdIdPermission);
542         setTextColumn(
543                 cursor,
544                 MeasurementTables.AsyncRegistrationContract.REGISTRATION_ID,
545                 builder::setRegistrationId);
546         setTextColumn(
547                 cursor,
548                 MeasurementTables.AsyncRegistrationContract.PLATFORM_AD_ID,
549                 builder::setPlatformAdId);
550         setTextColumn(
551                 cursor,
552                 MeasurementTables.AsyncRegistrationContract.REQUEST_POST_BODY,
553                 builder::setPostBody);
554         setTextColumn(
555                 cursor,
556                 MeasurementTables.AsyncRegistrationContract.REDIRECT_BEHAVIOR,
557                 (enumValue) ->
558                         builder.setRedirectBehavior(
559                                 enumValue == null
560                                         ? null
561                                         : AsyncRedirect.RedirectBehavior.valueOf(enumValue)));
562         return builder.build();
563     }
564 
565     /** Create {@link CountUniqueReport} object from SQLite datastore. */
constructCountUniqueReport(Cursor cursor)566     public static CountUniqueReport constructCountUniqueReport(Cursor cursor) {
567         CountUniqueReport.Builder builder = new CountUniqueReport.Builder();
568         setTextColumn(
569                 cursor,
570                 MeasurementTables.CountUniqueReportingContract.REPORT_ID,
571                 builder::setReportId);
572         setTextColumn(
573                 cursor,
574                 MeasurementTables.CountUniqueReportingContract.PAYLOAD,
575                 builder::setPayload);
576         setUriColumn(
577                 cursor,
578                 MeasurementTables.CountUniqueReportingContract.REPORTING_ORIGIN,
579                 builder::setReportingOrigin);
580         setIntColumn(
581                 cursor, MeasurementTables.CountUniqueReportingContract.STATUS, builder::setStatus);
582         setLongColumn(
583                 cursor,
584                 MeasurementTables.CountUniqueReportingContract.SCHEDULED_REPORT_TIME,
585                 builder::setScheduledReportTime);
586         setTextColumn(
587                 cursor,
588                 MeasurementTables.CountUniqueReportingContract.API_VERSION,
589                 builder::setApiVersion);
590         setTextColumn(
591                 cursor,
592                 MeasurementTables.CountUniqueReportingContract.DEBUG_KEY,
593                 builder::setDebugKey);
594         setTextColumn(
595                 cursor,
596                 MeasurementTables.CountUniqueReportingContract.CONTEXT_ID,
597                 builder::setContextId);
598         setIntColumn(
599                 cursor,
600                 MeasurementTables.CountUniqueReportingContract.DEBUG_REPORT_STATUS,
601                 builder::setDebugReportStatus);
602         setTextColumn(
603                 cursor,
604                 MeasurementTables.CountUniqueReportingContract.ENROLLMENT_ID,
605                 builder::setEnrollmentId);
606         setIntColumn(
607                 cursor,
608                 MeasurementTables.CountUniqueReportingContract.CONTRIBUTION_VALUE,
609                 builder::setContributionValue);
610         setLongColumn(
611                 cursor,
612                 MeasurementTables.CountUniqueReportingContract.CONTRIBUTION_TIME,
613                 builder::setContributionTime);
614         return builder.build();
615     }
616 
617     /**
618      * Create {@link com.android.adservices.service.measurement.CountUniqueMetadata} object from
619      * SQLite datastore.
620      */
constructCountUniqueMetadata(Cursor cursor)621     public static CountUniqueMetadata constructCountUniqueMetadata(Cursor cursor) {
622         CountUniqueMetadata.Builder builder = new CountUniqueMetadata.Builder();
623         setUriColumn(
624                 cursor,
625                 MeasurementTables.CountUniqueMetadataContract.REPORTING_ORIGIN,
626                 builder::setReportingOrigin);
627         setTextColumn(cursor, MeasurementTables.CountUniqueMetadataContract.KEY, builder::setKey);
628         setIntColumn(
629                 cursor, MeasurementTables.CountUniqueMetadataContract.VALUE, builder::setValue);
630         setLongColumn(
631                 cursor,
632                 MeasurementTables.CountUniqueMetadataContract.EXPIRATION_TIME,
633                 builder::setExpirationTime);
634         return builder.build();
635     }
636 
destinationsStringToList(String destinations)637     static List<Uri> destinationsStringToList(String destinations) {
638         return Arrays.stream(destinations.split(" "))
639                 .map(String::trim)
640                 .filter(not(String::isEmpty))
641                 .map(destination -> Uri.parse(destination))
642                 .collect(Collectors.toList());
643     }
644 
setUriColumn(Cursor cursor, String column, Function<Uri, BuilderType> setter)645     private static <BuilderType> void setUriColumn(Cursor cursor, String column, Function<Uri,
646             BuilderType> setter) {
647         setColumnValue(cursor, column, cursor::getString, (x) -> setter.apply(Uri.parse(x)));
648     }
649 
setIntColumn( Cursor cursor, String column, Function<Integer, BuilderType> setter)650     private static <BuilderType> void setIntColumn(
651             Cursor cursor, String column, Function<Integer, BuilderType> setter) {
652         setColumnValue(cursor, column, cursor::getInt, setter);
653     }
654 
setDoubleColumn(Cursor cursor, String column, Function<Double, BuilderType> setter)655     private static <BuilderType> void setDoubleColumn(Cursor cursor, String column,
656             Function<Double, BuilderType> setter) {
657         setColumnValue(cursor, column, cursor::getDouble, setter);
658     }
659 
setLongColumn(Cursor cursor, String column, Function<Long, BuilderType> setter)660     private static <BuilderType> void setLongColumn(Cursor cursor, String column,
661                                                     Function<Long, BuilderType> setter) {
662         setColumnValue(cursor, column, cursor::getLong, setter);
663     }
664 
setUnsignedLongColumn(Cursor cursor, String column, Function<UnsignedLong, BuilderType> setter)665     private static <BuilderType> void setUnsignedLongColumn(Cursor cursor, String column,
666                                                     Function<UnsignedLong, BuilderType> setter) {
667         setColumnValue(cursor, column, cursor::getLong, signedLong ->
668                 setter.apply(new UnsignedLong(signedLong)));
669     }
670 
setTextColumn(Cursor cursor, String column, Function<String, BuilderType> setter)671     private static <BuilderType> void setTextColumn(Cursor cursor, String column,
672                                                     Function<String, BuilderType> setter) {
673         setColumnValue(cursor, column, cursor::getString, setter);
674     }
675 
setBooleanColumn(Cursor cursor, String column, Function<Boolean, BuilderType> setter)676     private static <BuilderType> void setBooleanColumn(Cursor cursor, String column,
677             Function<Boolean, BuilderType> setter) {
678         setIntColumn(cursor, column, (x) -> setter.apply(x == 1));
679     }
680 
setColumnValue( Cursor cursor, String column, Function<Integer, DataType> getColVal, Function<DataType, BuilderType> setter)681     private static <BuilderType, DataType> void setColumnValue(
682             Cursor cursor, String column, Function<Integer, DataType> getColVal,
683             Function<DataType, BuilderType> setter) {
684         int index = cursor.getColumnIndex(column);
685         if (index > -1 && !cursor.isNull(index)) {
686             BuilderType unused = setter.apply(getColVal.apply(index));
687         }
688     }
689 
unsignedLongsStringToList(String concatArray)690     private static List<UnsignedLong> unsignedLongsStringToList(String concatArray) {
691         return getUnsignedLongStream(concatArray).collect(Collectors.toList());
692     }
693 
unsignedLongsStringToSet(String concatArray)694     private static Set<UnsignedLong> unsignedLongsStringToSet(String concatArray) {
695         return getUnsignedLongStream(concatArray).collect(Collectors.toSet());
696     }
697 
getUnsignedLongStream(String concatArray)698     private static Stream<UnsignedLong> getUnsignedLongStream(String concatArray) {
699         return Arrays.stream(concatArray.split(","))
700                 .map(String::trim)
701                 .filter(not(String::isEmpty))
702                 // TODO (b/295059367): Negative numbers handling to be reverted
703                 .map(parseCleanUnsignedLong());
704     }
705 
parseCleanUnsignedLong()706     private static Function<String, UnsignedLong> parseCleanUnsignedLong() {
707         return string -> {
708             if (string.startsWith("-")) {
709                 // It's in the long range
710                 return new UnsignedLong(Long.parseLong(string));
711             }
712             return new UnsignedLong(string);
713         };
714     }
715 }
716