chromium/content/browser/attribution_reporting/attribution_internals.mojom

// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

module attribution_internals.mojom;

import "components/attribution_reporting/registration.mojom";
import "components/attribution_reporting/source_type.mojom";
import "components/attribution_reporting/trigger_data_matching.mojom";
import "content/browser/attribution_reporting/aggregatable_result.mojom";
import "content/browser/attribution_reporting/process_aggregatable_debug_report_result.mojom";
import "content/browser/attribution_reporting/attribution_reporting.mojom";
import "content/browser/attribution_reporting/event_level_result.mojom";
import "content/browser/attribution_reporting/store_source_result.mojom";
import "services/network/public/mojom/attribution.mojom";
import "url/mojom/origin.mojom";
import "url/mojom/url.mojom";

// Represents `AttributionReport::Id`.
// Will be used to issue commands for individual reports.
struct ReportID {
  int64 value;
};

// Contains event-level data to be displayed.
struct WebUIReportEventLevelData {
  int64 priority;
  bool attributed_truthfully;
};

// Represents `AggregatableHistogramContribution`.
struct AggregatableHistogramContribution {
  // Hex-encoded unsigned 128-bit integer.
  string key;
  uint32 value;
};

// Contains aggregatable attribution data to be displayed.
struct WebUIReportAggregatableAttributionData {
  array<AggregatableHistogramContribution> contributions;
  string aggregation_coordinator;
  bool is_null_report;
};

union WebUIReportData {
  WebUIReportEventLevelData event_level_data;
  WebUIReportAggregatableAttributionData
      aggregatable_attribution_data;
};

struct Empty {};

union NetworkStatus {
  int32 http_response_code;
  string network_error;
};

union ReportStatus {
  Empty pending;
  // Contains the external report ID of the replacement report.
  string replaced_by_higher_priority_report;
  Empty prohibited_by_browser_policy;
  NetworkStatus network_status;
  Empty failed_to_assemble;
};

// Struct containing stored data that will be sent in a future attribution
// report.
struct WebUIReport {
  // Allows the WebUI to issue commands for individual reports.
  // Not intended to be displayed.
  ReportID id;
  url.mojom.Url report_url;
  double trigger_time;
  double report_time;
  string report_body;
  ReportStatus status;
  WebUIReportData data;
};

struct WebUIDebugReport {
  url.mojom.Url url;
  double time;
  string body;
  NetworkStatus status;
};

union SendAggregatableDebugReportResult {
  Empty assembly_failed;
  NetworkStatus network_status;
};

struct WebUIAggregatableDebugReport {
  url.mojom.Url url;
  // Contains msec since the Unix epoch, as returned by
  // base::Time::InMillisecondsFSinceUnixEpochIgnoringNull().
  double time;
  // Serialized JSON dictionary.
  string body;
  attribution_reporting.mojom.ProcessAggregatableDebugReportResult
      process_result;
  SendAggregatableDebugReportResult send_result;
};

// Struct representing a stored attribution source that will be displayed by WebUI.
struct WebUISource {
  // The source's internal ID, unique across all sources in storage.
  // Not intended to be displayed.
  int64 id;
  uint64 source_event_id;
  url.mojom.Origin source_origin;
  attribution_reporting.mojom.DestinationSet destinations;
  url.mojom.Origin reporting_origin;
  double source_time;
  double expiry_time;
  // String instead of mojo_base.mojom.DictionaryValue because the value is
  // simply displayed in the UI, never inspected. JSON is used instead of
  // attribution_reporting.mojom.TriggerSpecs to avoid complex TypeScript-based
  // formatting.
  string trigger_specs_json;
  double aggregatable_report_window_time;
  attribution_reporting.mojom.SourceType source_type;
  int64 priority;
  uint64? debug_key;
  array<uint64> dedup_keys;
  attribution_reporting.mojom.FilterData filter_data;
  // The value is a hex-encoded unsigned 128-bit integer.
  map<string, string> aggregation_keys;
  int32 remaining_aggregatable_attribution_budget;
  array<uint64> aggregatable_dedup_keys;
  attribution_reporting.mojom.TriggerDataMatching trigger_data_matching;
  double event_level_epsilon;
  bool debug_cookie_set;
  int32 remaining_aggregatable_debug_budget;
  // A hex-encoded 128-bit integer.
  string aggregatable_debug_key_piece;
  // String is used for the same reasons as described for `trigger_specs_json`.
  string attribution_scopes_data_json;

  enum Attributability {
    kAttributable,
    // The source was dropped due to `CommonSourceInfo::AttributionLogic::kNever`.
    kNoisedNever,
    // The source was dropped due to `CommonSourceInfo::AttributionLogic::kFalsely`.
    kNoisedFalsely,
    kReachedEventLevelAttributionLimit,
  };
  Attributability attributability;
};

struct WebUIRegistration {
  double time;
  url.mojom.Origin context_origin;
  url.mojom.Origin reporting_origin;
  // String instead of mojo_base.mojom.DictionaryValue because the value is
  // simply displayed in the UI, never inspected.
  string registration_json;
  uint64? cleared_debug_key;
};

struct WebUITrigger {
  WebUIRegistration registration;

  attribution_reporting.mojom.EventLevelResult event_level_result;
  attribution_reporting.mojom.AggregatableResult aggregatable_result;
};

struct WebUISourceRegistration {
  WebUIRegistration registration;
  attribution_reporting.mojom.SourceType type;
  attribution_reporting.mojom.StoreSourceResult status;
};

// Struct containing info of successfully passed OS registrations to be
// displayed as a log by WebUI.
struct WebUIOsRegistration {
  // Contains msec since the Unix epoch, as returned by
  // base::Time::InMillisecondsFSinceUnixEpochIgnoringNull().
  double time;
  url.mojom.Url registration_url;
  url.mojom.Origin top_level_origin;
  bool is_debug_key_allowed;
  bool debug_reporting;
  attribution_reporting.mojom.RegistrationType type;
  attribution_reporting.mojom.OsRegistrationResult result;
};

// Observer for events relevant to the attribution internals WebUI.
interface Observer {
  // Called when the sources in storage changed.
  OnSourcesChanged(array<WebUISource> sources);

  // Called when the reports in storage changed.
  OnReportsChanged(array<WebUIReport> reports);

  // Called when a source is registered, regardless of success or failure.
  OnSourceHandled(WebUISourceRegistration source);

  // Called when a report is sent or replaced in storage by a higher-priority
  // report.
  OnReportHandled(WebUIReport report);

  // Called when a verbose debug report is sent, regardless of success.
  OnDebugReportSent(WebUIDebugReport report);

  // Called when an aggregatable debug report is assembled and sent, regardless
  // of success.
  OnAggregatableDebugReportSent(WebUIAggregatableDebugReport report);

  // Called when a trigger is registered, regardless of success or failure.
  OnTriggerHandled(WebUITrigger trigger);

  // Called when an OS source or trigger is registered, regardless of success
  // or failure.
  OnOsRegistration(WebUIOsRegistration registration);

  // Called when debug mode is enabled or disabled in the WebUI's browsing
  // context.
  OnDebugModeChanged(bool debug_mode);
};

// Mojo interface for the attribution internals WebUI to communicate with the
// storage layer.
interface Handler {
  // Returns the state of the Attribution Reporting API in the WebUI's browsing context.
  // TODO(apaseltiner): Replace this polling-based interface with notifications.
  IsAttributionReportingEnabled() => (bool enabled,
                                      network.mojom.AttributionSupport attribution_support);

  // Sends the given report, ignoring delay, returning when the operation has
  // been completed and the report has been cleared from storage.
  SendReport(ReportID id) => ();

  // Deletes all persisted data for the attribution reporting API, returning when the
  // operation has been completed.
  ClearStorage() => ();
};

// Factory for Observer and Handler.
interface Factory {
  // Binds the observer and handler.
  Create(pending_remote<Observer> observer,
         pending_receiver<Handler> handler);
};