summaryrefslogtreecommitdiff
path: root/adservices/service-core/java/com/android/adservices/service/measurement/reporting
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-01-10 19:01:23 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-01-10 19:01:23 +0000
commit41e7bbcf3d375486769059090e15260dc92f16c7 (patch)
tree5c368873297b82c25a8ba866cbeda97cce94d9fc /adservices/service-core/java/com/android/adservices/service/measurement/reporting
parent4f73884441d6a5c6ba4af7e5026807822aa034a0 (diff)
parent7f6cf1d740d6f047507d8bd2bc07ab12496e8024 (diff)
downloadAdServices-aml_tz5_341510010.tar.gz
Snap for 11296156 from 7f6cf1d740d6f047507d8bd2bc07ab12496e8024 to mainline-tzdata5-releaseaml_tz5_341510070aml_tz5_341510050aml_tz5_341510010aml_tz5_341510010
Change-Id: I84e6c0df7ccbfafbe8dd398518474c2b7a676013
Diffstat (limited to 'adservices/service-core/java/com/android/adservices/service/measurement/reporting')
-rw-r--r--adservices/service-core/java/com/android/adservices/service/measurement/reporting/AggregateReportBody.java6
-rw-r--r--adservices/service-core/java/com/android/adservices/service/measurement/reporting/AggregateReportingJobHandler.java16
-rw-r--r--adservices/service-core/java/com/android/adservices/service/measurement/reporting/DebugReportApi.java1
-rw-r--r--adservices/service-core/java/com/android/adservices/service/measurement/reporting/DebugReportingJobHandler.java10
-rw-r--r--adservices/service-core/java/com/android/adservices/service/measurement/reporting/EventReportWindowCalcDelegate.java264
-rw-r--r--adservices/service-core/java/com/android/adservices/service/measurement/reporting/EventReportingJobHandler.java10
-rw-r--r--adservices/service-core/java/com/android/adservices/service/measurement/reporting/ReportingStatus.java8
7 files changed, 183 insertions, 132 deletions
diff --git a/adservices/service-core/java/com/android/adservices/service/measurement/reporting/AggregateReportBody.java b/adservices/service-core/java/com/android/adservices/service/measurement/reporting/AggregateReportBody.java
index a4d1971070..0498d4a85c 100644
--- a/adservices/service-core/java/com/android/adservices/service/measurement/reporting/AggregateReportBody.java
+++ b/adservices/service-core/java/com/android/adservices/service/measurement/reporting/AggregateReportBody.java
@@ -50,7 +50,8 @@ public class AggregateReportBody {
private static final String API_NAME = "attribution-reporting";
- private interface PayloadBodyKeys {
+ @VisibleForTesting
+ interface PayloadBodyKeys {
String SHARED_INFO = "shared_info";
String AGGREGATION_SERVICE_PAYLOADS = "aggregation_service_payloads";
String SOURCE_DEBUG_KEY = "source_debug_key";
@@ -64,7 +65,8 @@ public class AggregateReportBody {
String DEBUG_CLEARTEXT_PAYLOAD = "debug_cleartext_payload";
}
- private interface SharedInfoKeys {
+ @VisibleForTesting
+ interface SharedInfoKeys {
String API_NAME = "api";
String ATTRIBUTION_DESTINATION = "attribution_destination";
String REPORT_ID = "report_id";
diff --git a/adservices/service-core/java/com/android/adservices/service/measurement/reporting/AggregateReportingJobHandler.java b/adservices/service-core/java/com/android/adservices/service/measurement/reporting/AggregateReportingJobHandler.java
index 4367ee1b8b..849ec8164b 100644
--- a/adservices/service-core/java/com/android/adservices/service/measurement/reporting/AggregateReportingJobHandler.java
+++ b/adservices/service-core/java/com/android/adservices/service/measurement/reporting/AggregateReportingJobHandler.java
@@ -16,7 +16,10 @@
package com.android.adservices.service.measurement.reporting;
-import static com.android.adservices.service.stats.AdServicesStatsLog.AD_SERVICES_ERROR_REPORTED__ERROR_CODE__ERROR_CODE_UNSPECIFIED;
+import static com.android.adservices.service.stats.AdServicesStatsLog.AD_SERVICES_ERROR_REPORTED__ERROR_CODE__MEASUREMENT_REPORTING_ENCRYPTION_ERROR;
+import static com.android.adservices.service.stats.AdServicesStatsLog.AD_SERVICES_ERROR_REPORTED__ERROR_CODE__MEASUREMENT_REPORTING_NETWORK_ERROR;
+import static com.android.adservices.service.stats.AdServicesStatsLog.AD_SERVICES_ERROR_REPORTED__ERROR_CODE__MEASUREMENT_REPORTING_PARSING_ERROR;
+import static com.android.adservices.service.stats.AdServicesStatsLog.AD_SERVICES_ERROR_REPORTED__ERROR_CODE__MEASUREMENT_REPORTING_UNKNOWN_ERROR;
import static com.android.adservices.service.stats.AdServicesStatsLog.AD_SERVICES_ERROR_REPORTED__PPAPI_NAME__MEASUREMENT;
import static com.android.adservices.service.stats.AdServicesStatsLog.AD_SERVICES_MESUREMENT_REPORTS_UPLOADED;
@@ -289,7 +292,7 @@ public class AggregateReportingJobHandler {
// TODO(b/298330312): Change to defined error codes
ErrorLogUtil.e(
e,
- AD_SERVICES_ERROR_REPORTED__ERROR_CODE__ERROR_CODE_UNSPECIFIED,
+ AD_SERVICES_ERROR_REPORTED__ERROR_CODE__MEASUREMENT_REPORTING_NETWORK_ERROR,
AD_SERVICES_ERROR_REPORTED__PPAPI_NAME__MEASUREMENT);
return AdServicesStatusUtils.STATUS_IO_ERROR;
} catch (JSONException e) {
@@ -299,7 +302,7 @@ public class AggregateReportingJobHandler {
// TODO(b/298330312): Change to defined error codes
ErrorLogUtil.e(
e,
- AD_SERVICES_ERROR_REPORTED__ERROR_CODE__ERROR_CODE_UNSPECIFIED,
+ AD_SERVICES_ERROR_REPORTED__ERROR_CODE__MEASUREMENT_REPORTING_PARSING_ERROR,
AD_SERVICES_ERROR_REPORTED__PPAPI_NAME__MEASUREMENT);
if (mFlags.getMeasurementEnableReportDeletionOnUnrecoverableException()) {
// Unrecoverable state - delete the report.
@@ -324,7 +327,7 @@ public class AggregateReportingJobHandler {
// TODO(b/298330312): Change to defined error codes
ErrorLogUtil.e(
e,
- AD_SERVICES_ERROR_REPORTED__ERROR_CODE__ERROR_CODE_UNSPECIFIED,
+ AD_SERVICES_ERROR_REPORTED__ERROR_CODE__MEASUREMENT_REPORTING_ENCRYPTION_ERROR,
AD_SERVICES_ERROR_REPORTED__PPAPI_NAME__MEASUREMENT);
if (mFlags.getMeasurementEnableReportingJobsThrowCryptoException()
&& ThreadLocalRandom.current().nextFloat()
@@ -338,7 +341,7 @@ public class AggregateReportingJobHandler {
// TODO(b/298330312): Change to defined error codes
ErrorLogUtil.e(
e,
- AD_SERVICES_ERROR_REPORTED__ERROR_CODE__ERROR_CODE_UNSPECIFIED,
+ AD_SERVICES_ERROR_REPORTED__ERROR_CODE__MEASUREMENT_REPORTING_UNKNOWN_ERROR,
AD_SERVICES_ERROR_REPORTED__PPAPI_NAME__MEASUREMENT);
if (mFlags.getMeasurementEnableReportingJobsThrowUnaccountedException()
&& ThreadLocalRandom.current().nextFloat()
@@ -371,8 +374,7 @@ public class AggregateReportingJobHandler {
.setTriggerDebugKey(aggregateReport.getTriggerDebugKey())
.setAggregationCoordinatorOrigin(aggregateReport.getAggregationCoordinatorOrigin())
.setDebugMode(
- mIsDebugInstance
- && aggregateReport.getSourceDebugKey() != null
+ aggregateReport.getSourceDebugKey() != null
&& aggregateReport.getTriggerDebugKey() != null
? "enabled"
: null)
diff --git a/adservices/service-core/java/com/android/adservices/service/measurement/reporting/DebugReportApi.java b/adservices/service-core/java/com/android/adservices/service/measurement/reporting/DebugReportApi.java
index c4a6d7201e..778570c249 100644
--- a/adservices/service-core/java/com/android/adservices/service/measurement/reporting/DebugReportApi.java
+++ b/adservices/service-core/java/com/android/adservices/service/measurement/reporting/DebugReportApi.java
@@ -80,6 +80,7 @@ public class DebugReportApi {
String TRIGGER_UNKNOWN_ERROR = "trigger-unknown-error";
String TRIGGER_AGGREGATE_STORAGE_LIMIT = "trigger-aggregate-storage-limit";
String TRIGGER_AGGREGATE_EXCESSIVE_REPORTS = "trigger-aggregate-excessive-reports";
+ String TRIGGER_EVENT_REPORT_WINDOW_NOT_STARTED = "trigger-event-report-window-not-started";
}
/** Defines different verbose debug report body parameters. */
diff --git a/adservices/service-core/java/com/android/adservices/service/measurement/reporting/DebugReportingJobHandler.java b/adservices/service-core/java/com/android/adservices/service/measurement/reporting/DebugReportingJobHandler.java
index 0650f67e90..4391b37254 100644
--- a/adservices/service-core/java/com/android/adservices/service/measurement/reporting/DebugReportingJobHandler.java
+++ b/adservices/service-core/java/com/android/adservices/service/measurement/reporting/DebugReportingJobHandler.java
@@ -16,7 +16,9 @@
package com.android.adservices.service.measurement.reporting;
-import static com.android.adservices.service.stats.AdServicesStatsLog.AD_SERVICES_ERROR_REPORTED__ERROR_CODE__ERROR_CODE_UNSPECIFIED;
+import static com.android.adservices.service.stats.AdServicesStatsLog.AD_SERVICES_ERROR_REPORTED__ERROR_CODE__MEASUREMENT_REPORTING_NETWORK_ERROR;
+import static com.android.adservices.service.stats.AdServicesStatsLog.AD_SERVICES_ERROR_REPORTED__ERROR_CODE__MEASUREMENT_REPORTING_PARSING_ERROR;
+import static com.android.adservices.service.stats.AdServicesStatsLog.AD_SERVICES_ERROR_REPORTED__ERROR_CODE__MEASUREMENT_REPORTING_UNKNOWN_ERROR;
import static com.android.adservices.service.stats.AdServicesStatsLog.AD_SERVICES_ERROR_REPORTED__PPAPI_NAME__MEASUREMENT;
import static com.android.adservices.service.stats.AdServicesStatsLog.AD_SERVICES_MESUREMENT_REPORTS_UPLOADED;
@@ -184,7 +186,7 @@ public class DebugReportingJobHandler {
.d(e, "Network error occurred when attempting to deliver debug report.");
ErrorLogUtil.e(
e,
- AD_SERVICES_ERROR_REPORTED__ERROR_CODE__ERROR_CODE_UNSPECIFIED,
+ AD_SERVICES_ERROR_REPORTED__ERROR_CODE__MEASUREMENT_REPORTING_NETWORK_ERROR,
AD_SERVICES_ERROR_REPORTED__PPAPI_NAME__MEASUREMENT);
reportingStatus.setFailureStatus(ReportingStatus.FailureStatus.NETWORK);
// TODO(b/298330312): Change to defined error codes
@@ -195,7 +197,7 @@ public class DebugReportingJobHandler {
// TODO(b/298330312): Change to defined error codes
ErrorLogUtil.e(
e,
- AD_SERVICES_ERROR_REPORTED__ERROR_CODE__ERROR_CODE_UNSPECIFIED,
+ AD_SERVICES_ERROR_REPORTED__ERROR_CODE__MEASUREMENT_REPORTING_PARSING_ERROR,
AD_SERVICES_ERROR_REPORTED__PPAPI_NAME__MEASUREMENT);
reportingStatus.setFailureStatus(ReportingStatus.FailureStatus.SERIALIZATION_ERROR);
if (mFlags.getMeasurementEnableReportDeletionOnUnrecoverableException()) {
@@ -216,7 +218,7 @@ public class DebugReportingJobHandler {
// TODO(b/298330312): Change to defined error codes
ErrorLogUtil.e(
e,
- AD_SERVICES_ERROR_REPORTED__ERROR_CODE__ERROR_CODE_UNSPECIFIED,
+ AD_SERVICES_ERROR_REPORTED__ERROR_CODE__MEASUREMENT_REPORTING_UNKNOWN_ERROR,
AD_SERVICES_ERROR_REPORTED__PPAPI_NAME__MEASUREMENT);
reportingStatus.setFailureStatus(ReportingStatus.FailureStatus.UNKNOWN);
if (mFlags.getMeasurementEnableReportingJobsThrowUnaccountedException()
diff --git a/adservices/service-core/java/com/android/adservices/service/measurement/reporting/EventReportWindowCalcDelegate.java b/adservices/service-core/java/com/android/adservices/service/measurement/reporting/EventReportWindowCalcDelegate.java
index 9d7564c43c..93f7913854 100644
--- a/adservices/service-core/java/com/android/adservices/service/measurement/reporting/EventReportWindowCalcDelegate.java
+++ b/adservices/service-core/java/com/android/adservices/service/measurement/reporting/EventReportWindowCalcDelegate.java
@@ -54,36 +54,42 @@ public class EventReportWindowCalcDelegate {
}
/**
- * Max reports count based on conversion destination type and installation state.
+ * Max reports count given the Source object.
*
- * @param isInstallCase is app installed
+ * @param source the Source object
* @return maximum number of reports allowed
*/
- public int getMaxReportCount(@NonNull Source source, boolean isInstallCase) {
+ public int getMaxReportCount(Source source) {
+ return getMaxReportCount(source, source.isInstallDetectionEnabled());
+ }
+
+ /**
+ * Max reports count based on conversion destination type.
+ *
+ * @param source the Source object
+ * @param destinationType destination type
+ * @return maximum number of reports allowed
+ */
+ public int getMaxReportCount(@NonNull Source source, @EventSurfaceType int destinationType) {
+ return getMaxReportCount(source, isInstallCase(source, destinationType));
+ }
+
+ private int getMaxReportCount(@NonNull Source source, boolean isInstallCase) {
// TODO(b/290101531): Cleanup flags
if (mFlags.getMeasurementFlexLiteApiEnabled() && source.getMaxEventLevelReports() != null) {
return source.getMaxEventLevelReports();
}
- if (source.getSourceType() == Source.SourceType.EVENT
- && mFlags.getMeasurementEnableVtcConfigurableMaxEventReports()) {
- // Max VTC event reports are configurable
- int configuredMaxReports = mFlags.getMeasurementVtcConfigurableMaxEventReportsCount();
+
+ if (source.getSourceType() == Source.SourceType.EVENT) {
// Additional report essentially for first open + 1 post install conversion. If there
// is already more than 1 report allowed, no need to have that additional report.
- if (isInstallCase && configuredMaxReports == PrivacyParams.EVENT_SOURCE_MAX_REPORTS) {
+ if (isInstallCase && !source.hasWebDestinations() && isDefaultConfiguredVtc()) {
return PrivacyParams.INSTALL_ATTR_EVENT_SOURCE_MAX_REPORTS;
}
- return configuredMaxReports;
+ return mFlags.getMeasurementVtcConfigurableMaxEventReportsCount();
}
- if (isInstallCase) {
- return source.getSourceType() == Source.SourceType.EVENT
- ? PrivacyParams.INSTALL_ATTR_EVENT_SOURCE_MAX_REPORTS
- : PrivacyParams.INSTALL_ATTR_NAVIGATION_SOURCE_MAX_REPORTS;
- }
- return source.getSourceType() == Source.SourceType.EVENT
- ? PrivacyParams.EVENT_SOURCE_MAX_REPORTS
- : PrivacyParams.NAVIGATION_SOURCE_MAX_REPORTS;
+ return PrivacyParams.NAVIGATION_SOURCE_MAX_REPORTS;
}
/**
@@ -100,18 +106,14 @@ public class EventReportWindowCalcDelegate {
// Cases where source could have both web and app destinations, there if the trigger
// destination is an app, and it was installed, then installState should be considered true.
- boolean isAppInstalled = isAppInstalled(source, destinationType);
- List<Pair<Long, Long>> earlyReportingWindows =
- getEarlyReportingWindows(source, isAppInstalled);
- for (Pair<Long, Long> window : earlyReportingWindows) {
+ List<Pair<Long, Long>> reportingWindows =
+ getEffectiveReportingWindows(source, isInstallCase(source, destinationType));
+ for (Pair<Long, Long> window : reportingWindows) {
if (isWithinWindow(triggerTime, window)) {
return window.second + mFlags.getMeasurementMinEventReportDelayMillis();
}
}
- Pair<Long, Long> finalWindow = getFinalReportingWindow(source, earlyReportingWindows);
- if (isWithinWindow(triggerTime, finalWindow)) {
- return finalWindow.second + mFlags.getMeasurementMinEventReportDelayMillis();
- }
+
return -1;
}
@@ -120,45 +122,60 @@ public class EventReportWindowCalcDelegate {
}
/**
+ * Enum shows trigger time and source window time relationship. It is used to generate different
+ * verbose debug reports.
+ */
+ public enum MomentPlacement {
+ BEFORE,
+ AFTER,
+ WITHIN;
+ }
+
+ /**
+ * @param source source for which the window is calculated
+ * @param triggerTime time for the trigger
+ * @param destinationType trigger destination type
+ * @return how trigger time falls in source windows
+ */
+ public MomentPlacement fallsWithinWindow(
+ @NonNull Source source, long triggerTime, @EventSurfaceType int destinationType) {
+ List<Pair<Long, Long>> reportingWindows =
+ getEffectiveReportingWindows(source, isInstallCase(source, destinationType));
+ if (triggerTime < reportingWindows.get(0).first) {
+ return MomentPlacement.BEFORE;
+ }
+ if (triggerTime >= reportingWindows.get(reportingWindows.size() - 1).second) {
+ return MomentPlacement.AFTER;
+ }
+ return MomentPlacement.WITHIN;
+ }
+
+ /**
* Return reporting time by index for noising based on the index
*
* @param windowIndex index of the reporting window for which
* @return reporting time in milliseconds
*/
public long getReportingTimeForNoising(
- @NonNull Source source, int windowIndex, boolean isInstallCase) {
- List<Pair<Long, Long>> earlyWindows = getEarlyReportingWindows(source, isInstallCase);
- Pair<Long, Long> finalWindow = getFinalReportingWindow(source, earlyWindows);
- return windowIndex < earlyWindows.size()
- ? earlyWindows.get(windowIndex).second
+ @NonNull Source source, int windowIndex) {
+ List<Pair<Long, Long>> reportingWindows = getEffectiveReportingWindows(
+ source, source.isInstallDetectionEnabled());
+ Pair<Long, Long> finalWindow = reportingWindows.get(reportingWindows.size() - 1);
+ // TODO: (b/288646239) remove this check, confirming noising indexing accuracy.
+ return windowIndex < reportingWindows.size()
+ ? reportingWindows.get(windowIndex).second
+ mFlags.getMeasurementMinEventReportDelayMillis()
: finalWindow.second + mFlags.getMeasurementMinEventReportDelayMillis();
}
- private Pair<Long, Long> getFinalReportingWindow(
- Source source, List<Pair<Long, Long>> earlyWindows) {
- if (mFlags.getMeasurementFlexLiteApiEnabled() && source.hasManualEventReportWindows()) {
- List<Pair<Long, Long>> windowList = source.parsedProcessedEventReportWindows();
- return windowList.get(windowList.size() - 1);
- }
- long secondToLastWindowEnd =
- !earlyWindows.isEmpty() ? earlyWindows.get(earlyWindows.size() - 1).second : 0;
- if (source.getProcessedEventReportWindow() != null) {
- return new Pair<>(secondToLastWindowEnd, source.getProcessedEventReportWindow());
- }
- return new Pair<>(secondToLastWindowEnd, source.getExpiryTime());
- }
-
/**
- * Returns effective, i.e. the ones that occur before {@link
- * Source#getProcessedEventReportWindow()}, event reporting windows count for noising cases.
+ * Returns effective, that is, the ones that occur before {@link
+ * Source#getEffectiveEventReportWindow()}, event reporting windows count for noising cases.
*
* @param source source for which the count is requested
- * @param isInstallCase true of cool down window was specified
*/
- public int getReportingWindowCountForNoising(@NonNull Source source, boolean isInstallCase) {
- // Early Count + lastWindow
- return getEarlyReportingWindows(source, isInstallCase).size() + 1;
+ public int getReportingWindowCountForNoising(@NonNull Source source) {
+ return getEffectiveReportingWindows(source, source.isInstallDetectionEnabled()).size();
}
/**
@@ -213,47 +230,53 @@ public class EventReportWindowCalcDelegate {
return -1L;
}
- private boolean isAppInstalled(Source source, int destinationType) {
+ private static boolean isInstallCase(Source source, @EventSurfaceType int destinationType) {
return destinationType == EventSurfaceType.APP && source.isInstallAttributed();
}
/**
* If the flag is enabled and the specified report windows are valid, picks from flag controlled
- * configurable early reporting windows. Otherwise, falls back to the statical {@link
- * com.android.adservices.service.measurement.PrivacyParams} values. It curtails the windows
- * that occur after {@link Source#getProcessedEventReportWindow()} because they would
- * effectively be unusable.
+ * configurable early reporting windows. Otherwise, falls back to the values provided in
+ * {@code getDefaultEarlyReportingWindowEnds}, which can have install-related custom behaviour.
+ * It curtails the windows that occur after {@link Source#getEffectiveEventReportWindow()}
+ * because they would effectively be unusable.
*/
- private List<Pair<Long, Long>> getEarlyReportingWindows(Source source, boolean installState) {
+ private List<Pair<Long, Long>> getEffectiveReportingWindows(Source source,
+ boolean installState) {
// TODO(b/290221611) Remove early reporting windows from code, only use them for flags.
if (mFlags.getMeasurementFlexLiteApiEnabled() && source.hasManualEventReportWindows()) {
- List<Pair<Long, Long>> windows = source.parsedProcessedEventReportWindows();
- // Select early windows only i.e. skip the last element
- return windows.subList(0, windows.size() - 1);
+ return source.parsedProcessedEventReportWindows();
}
- List<Long> earlyWindows;
- List<Long> defaultEarlyWindows =
- getDefaultEarlyReportingWindows(source.getSourceType(), installState);
- earlyWindows =
- getConfiguredOrDefaultEarlyReportingWindows(
- source.getSourceType(), defaultEarlyWindows, true);
+ List<Long> defaultEarlyWindowEnds =
+ getDefaultEarlyReportingWindowEnds(
+ source.getSourceType(),
+ installState && !source.hasWebDestinations());
+ List<Long> earlyWindowEnds =
+ getConfiguredOrDefaultEarlyReportingWindowEnds(
+ source.getSourceType(), defaultEarlyWindowEnds);
// Add source event time to windows
- earlyWindows =
- earlyWindows.stream()
+ earlyWindowEnds =
+ earlyWindowEnds.stream()
.map((x) -> source.getEventTime() + x)
.collect(Collectors.toList());
List<Pair<Long, Long>> windowList = new ArrayList<>();
- long windowStart = 0;
+ long windowStart = 0L;
Pair<Long, Long> finalWindow =
- getFinalReportingWindow(source, createStartEndWindow(earlyWindows));
- for (long windowEnd : earlyWindows) {
- if (finalWindow.second <= windowEnd) {
- continue;
+ getFinalReportingWindow(source, earlyWindowEnds);
+
+ for (long windowEnd : earlyWindowEnds) {
+ // Start time of `finalWindow` is either 0 or one of `earlyWindowEnds` times; stop
+ // iterating if we see it, and add `finalWindow`.
+ if (windowStart == finalWindow.first) {
+ break;
}
- windowList.add(new Pair<>(windowStart, windowEnd));
+ windowList.add(Pair.create(windowStart, windowEnd));
windowStart = windowEnd;
}
+
+ windowList.add(finalWindow);
+
return ImmutableList.copyOf(windowList);
}
@@ -261,13 +284,13 @@ public class EventReportWindowCalcDelegate {
* Returns the default early reporting windows
*
* @param sourceType Source's Type
- * @param installState Install State of the source
+ * @param installAttributionEnabled whether windows for install attribution should be provided
* @return a list of windows
*/
- public static List<Long> getDefaultEarlyReportingWindows(
- Source.SourceType sourceType, boolean installState) {
+ public static List<Long> getDefaultEarlyReportingWindowEnds(
+ Source.SourceType sourceType, boolean installAttributionEnabled) {
long[] earlyWindows;
- if (installState) {
+ if (installAttributionEnabled) {
earlyWindows =
sourceType == Source.SourceType.EVENT
? INSTALL_ATTR_EVENT_EARLY_REPORTING_WINDOW_MILLISECONDS
@@ -281,53 +304,34 @@ public class EventReportWindowCalcDelegate {
return asList(earlyWindows);
}
- private List<Pair<Long, Long>> createStartEndWindow(List<Long> windowEnds) {
- List<Pair<Long, Long>> windows = new ArrayList<>();
- long start = 0;
- for (Long end : windowEnds) {
- windows.add(new Pair<>(start, end));
- start = end;
- }
- return windows;
- }
-
/**
* Returns default or configured (via flag) early reporting windows for the SourceType
*
* @param sourceType Source's Type
* @param defaultEarlyWindows default value for early windows
- * @param checkEnableFlag set true if configurable window flag should be checked
* @return list of windows
*/
- public List<Long> getConfiguredOrDefaultEarlyReportingWindows(
- Source.SourceType sourceType, List<Long> defaultEarlyWindows, boolean checkEnableFlag) {
- // TODO(b/290101531): Cleanup flags
- if (checkEnableFlag && !mFlags.getMeasurementEnableConfigurableEventReportingWindows()) {
- return defaultEarlyWindows;
+ public List<Long> getConfiguredOrDefaultEarlyReportingWindowEnds(
+ Source.SourceType sourceType, List<Long> defaultEarlyWindowEnds) {
+ // `defaultEarlyWindowEnds` may contain custom install-related logic, which we only apply if
+ // the configurable report windows (and max reports) are in their default state. Without
+ // this check, we may construct default-value report windows without the custom
+ // install-related logic applied.
+ if ((sourceType == Source.SourceType.EVENT && isDefaultConfiguredVtc())
+ || (sourceType == Source.SourceType.NAVIGATION && isDefaultConfiguredCtc())) {
+ return defaultEarlyWindowEnds;
}
String earlyReportingWindowsString = pickEarlyReportingWindowsConfig(mFlags, sourceType);
- if (earlyReportingWindowsString == null) {
- LoggerFactory.getMeasurementLogger()
- .d("Invalid configurable early reporting windows; null");
- return defaultEarlyWindows;
- }
-
if (earlyReportingWindowsString.isEmpty()) {
// No early reporting windows specified. It needs to be handled separately because
- // splitting an empty string results into an array containing a single element,
- // i.e. "". We want to handle it as an array having no element.
-
- if (Source.SourceType.EVENT.equals(sourceType)) {
- // We need to add a reporting window at 2d for post-install case. Non-install case
- // has no early reporting window by default.
- return defaultEarlyWindows;
- }
+ // splitting an empty string results in an array containing a single empty string. We
+ // want to handle it as an empty array.
return Collections.emptyList();
}
- ImmutableList.Builder<Long> earlyWindows = new ImmutableList.Builder<>();
+ ImmutableList.Builder<Long> earlyWindowEnds = new ImmutableList.Builder<>();
String[] split =
earlyReportingWindowsString.split(EARLY_REPORTING_WINDOWS_CONFIG_DELIMITER);
if (split.length > MAX_CONFIGURABLE_EVENT_REPORT_EARLY_REPORTING_WINDOWS) {
@@ -335,22 +339,54 @@ public class EventReportWindowCalcDelegate {
.d(
"Invalid configurable early reporting window; more than allowed size: "
+ MAX_CONFIGURABLE_EVENT_REPORT_EARLY_REPORTING_WINDOWS);
- return defaultEarlyWindows;
+ return defaultEarlyWindowEnds;
}
- for (String window : split) {
+ for (String windowEnd : split) {
try {
- earlyWindows.add(TimeUnit.SECONDS.toMillis(Long.parseLong(window)));
+ earlyWindowEnds.add(TimeUnit.SECONDS.toMillis(Long.parseLong(windowEnd)));
} catch (NumberFormatException e) {
LoggerFactory.getMeasurementLogger()
.d(e, "Configurable early reporting window parsing failed.");
- return defaultEarlyWindows;
+ return defaultEarlyWindowEnds;
+ }
+ }
+ return earlyWindowEnds.build();
+ }
+
+ private Pair<Long, Long> getFinalReportingWindow(
+ Source source, List<Long> earlyWindowEnds) {
+ // The latest end-time we can associate with a report for this source
+ long effectiveExpiry = Math.min(
+ source.getEffectiveEventReportWindow(), source.getExpiryTime());
+ // Find the latest end-time that can start a window ending at effectiveExpiry
+ for (int i = earlyWindowEnds.size() - 1; i >= 0; i--) {
+ long windowEnd = earlyWindowEnds.get(i);
+ if (windowEnd < effectiveExpiry) {
+ return Pair.create(windowEnd, effectiveExpiry);
}
}
- return earlyWindows.build();
+ return Pair.create(0L, effectiveExpiry);
+ }
+
+ /** Indicates whether VTC report windows and max reports are default configured, which can
+ * affect custom install-related attribution.
+ */
+ public boolean isDefaultConfiguredVtc() {
+ return mFlags.getMeasurementEventReportsVtcEarlyReportingWindows().isEmpty()
+ && mFlags.getMeasurementVtcConfigurableMaxEventReportsCount() == 1;
+ }
+
+ /** Indicates whether CTC report windows are default configured, which can affect custom
+ * install-related attribution.
+ */
+ private boolean isDefaultConfiguredCtc() {
+ return mFlags.getMeasurementEventReportsCtcEarlyReportingWindows().equals(
+ Flags.MEASUREMENT_EVENT_REPORTS_CTC_EARLY_REPORTING_WINDOWS);
}
- private String pickEarlyReportingWindowsConfig(Flags flags, Source.SourceType sourceType) {
+ private static String pickEarlyReportingWindowsConfig(Flags flags,
+ Source.SourceType sourceType) {
return sourceType == Source.SourceType.EVENT
? flags.getMeasurementEventReportsVtcEarlyReportingWindows()
: flags.getMeasurementEventReportsCtcEarlyReportingWindows();
diff --git a/adservices/service-core/java/com/android/adservices/service/measurement/reporting/EventReportingJobHandler.java b/adservices/service-core/java/com/android/adservices/service/measurement/reporting/EventReportingJobHandler.java
index f5042f3afd..c67f0acd67 100644
--- a/adservices/service-core/java/com/android/adservices/service/measurement/reporting/EventReportingJobHandler.java
+++ b/adservices/service-core/java/com/android/adservices/service/measurement/reporting/EventReportingJobHandler.java
@@ -16,7 +16,9 @@
package com.android.adservices.service.measurement.reporting;
-import static com.android.adservices.service.stats.AdServicesStatsLog.AD_SERVICES_ERROR_REPORTED__ERROR_CODE__ERROR_CODE_UNSPECIFIED;
+import static com.android.adservices.service.stats.AdServicesStatsLog.AD_SERVICES_ERROR_REPORTED__ERROR_CODE__MEASUREMENT_REPORTING_NETWORK_ERROR;
+import static com.android.adservices.service.stats.AdServicesStatsLog.AD_SERVICES_ERROR_REPORTED__ERROR_CODE__MEASUREMENT_REPORTING_PARSING_ERROR;
+import static com.android.adservices.service.stats.AdServicesStatsLog.AD_SERVICES_ERROR_REPORTED__ERROR_CODE__MEASUREMENT_REPORTING_UNKNOWN_ERROR;
import static com.android.adservices.service.stats.AdServicesStatsLog.AD_SERVICES_ERROR_REPORTED__PPAPI_NAME__MEASUREMENT;
import static com.android.adservices.service.stats.AdServicesStatsLog.AD_SERVICES_MESUREMENT_REPORTS_UPLOADED;
@@ -270,7 +272,7 @@ public class EventReportingJobHandler {
// TODO(b/298330312): Change to defined error codes
ErrorLogUtil.e(
e,
- AD_SERVICES_ERROR_REPORTED__ERROR_CODE__ERROR_CODE_UNSPECIFIED,
+ AD_SERVICES_ERROR_REPORTED__ERROR_CODE__MEASUREMENT_REPORTING_NETWORK_ERROR,
AD_SERVICES_ERROR_REPORTED__PPAPI_NAME__MEASUREMENT);
return AdServicesStatusUtils.STATUS_IO_ERROR;
} catch (JSONException e) {
@@ -281,7 +283,7 @@ public class EventReportingJobHandler {
// TODO(b/298330312): Change to defined error codes
ErrorLogUtil.e(
e,
- AD_SERVICES_ERROR_REPORTED__ERROR_CODE__ERROR_CODE_UNSPECIFIED,
+ AD_SERVICES_ERROR_REPORTED__ERROR_CODE__MEASUREMENT_REPORTING_PARSING_ERROR,
AD_SERVICES_ERROR_REPORTED__PPAPI_NAME__MEASUREMENT);
if (mFlags.getMeasurementEnableReportDeletionOnUnrecoverableException()) {
// Unrecoverable state - delete the report.
@@ -305,7 +307,7 @@ public class EventReportingJobHandler {
reportingStatus.setFailureStatus(ReportingStatus.FailureStatus.UNKNOWN);
ErrorLogUtil.e(
e,
- AD_SERVICES_ERROR_REPORTED__ERROR_CODE__ERROR_CODE_UNSPECIFIED,
+ AD_SERVICES_ERROR_REPORTED__ERROR_CODE__MEASUREMENT_REPORTING_UNKNOWN_ERROR,
AD_SERVICES_ERROR_REPORTED__PPAPI_NAME__MEASUREMENT);
if (mFlags.getMeasurementEnableReportingJobsThrowUnaccountedException()
&& ThreadLocalRandom.current().nextFloat()
diff --git a/adservices/service-core/java/com/android/adservices/service/measurement/reporting/ReportingStatus.java b/adservices/service-core/java/com/android/adservices/service/measurement/reporting/ReportingStatus.java
index 8e7b1780fe..4e83edb8c9 100644
--- a/adservices/service-core/java/com/android/adservices/service/measurement/reporting/ReportingStatus.java
+++ b/adservices/service-core/java/com/android/adservices/service/measurement/reporting/ReportingStatus.java
@@ -52,7 +52,9 @@ public class ReportingStatus {
VERBOSE_DEBUG_TRIGGER_UNKNOWN_ERROR(26),
VERBOSE_DEBUG_TRIGGER_AGGREGATE_STORAGE_LIMIT(27),
VERBOSE_DEBUG_TRIGGER_AGGREGATE_EXCESSIVE_REPORTS(28),
- VERBOSE_DEBUG_UNKNOWN(29);
+ VERBOSE_DEBUG_TRIGGER_EVENT_REPORT_WINDOW_NOT_STARTED(29),
+ VERBOSE_DEBUG_UNKNOWN(9999);
+
private final int mValue;
ReportType(int value) {
@@ -202,6 +204,10 @@ public class ReportingStatus {
mReportType = ReportType.VERBOSE_DEBUG_TRIGGER_AGGREGATE_STORAGE_LIMIT;
} else if (reportType.equals(DebugReportApi.Type.TRIGGER_AGGREGATE_EXCESSIVE_REPORTS)) {
mReportType = ReportType.VERBOSE_DEBUG_TRIGGER_AGGREGATE_EXCESSIVE_REPORTS;
+ } else if (reportType.equals(DebugReportApi.Type.TRIGGER_EVENT_REPORT_WINDOW_NOT_STARTED)) {
+ mReportType = ReportType.VERBOSE_DEBUG_TRIGGER_EVENT_REPORT_WINDOW_NOT_STARTED;
+ } else {
+ mReportType = ReportType.VERBOSE_DEBUG_UNKNOWN;
}
}