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

module content.mojom;

import "content/common/native_types.mojom";
import "content/common/service_worker/controller_service_worker.mojom";
import "content/common/service_worker/service_worker.mojom";
import "content/common/service_worker/service_worker_provider.mojom";
import "content/common/url_loader_factory_bundle.mojom";
import "content/public/common/renderer_preference_watcher.mojom";
import "content/public/common/renderer_preferences.mojom";
import "mojo/public/mojom/base/string16.mojom";
import "mojo/public/mojom/base/time.mojom";
import "mojo/public/mojom/base/unguessable_token.mojom";
import "services/service_manager/public/mojom/interface_provider.mojom";
import "third_party/blink/public/mojom/service_worker/service_worker_installed_scripts_manager.mojom";
import "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom";
import "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom";
import "third_party/blink/public/platform/web_feature.mojom";
import "third_party/blink/public/web/console_message.mojom";
import "third_party/blink/public/web/devtools_agent.mojom";
import "third_party/blink/public/web/worker_content_settings_proxy.mojom";
import "url/mojom/url.mojom";

// Parameters to launch a service worker. This is passed from the browser to the
// renderer at mojom::EmbeddedWorkerInstanceClient::StartWorker().
struct EmbeddedWorkerStartParams {
  // The id of the embedded worker. This changes when the service worker is
  // stopped and restarted.
  int32 embedded_worker_id;
  // The id of the service worker being started. This remains fixed even if the
  // worker is stopped and restarted, or even if the browser restarts.
  int64 service_worker_version_id;
  // This service worker's registration's scope:
  // https://w3c.github.io/ServiceWorker/#service-worker-registration-scope
  url.mojom.Url scope;
  // This service worker's script url:
  // https://w3c.github.io/ServiceWorker/#dom-serviceworker-scripturl
  url.mojom.Url script_url;
  // This service worker's script type:
  // https://w3c.github.io/ServiceWorker/#dfn-type
  blink.mojom.ScriptType script_type;
  // The id to talk with the DevTools agent for the worker.
  int32 worker_devtools_agent_route_id;
  // Unique token identifying this worker for DevTools.
  mojo_base.mojom.UnguessableToken devtools_worker_token;
  // When true, worker script evaluation is blocked until
  // EmbeddedWorkerInstanceClient::ResumeAfterDownload() is called.
  bool pause_after_download;
  // True if starting the worker should wait until DevTools gets ready.
  bool wait_for_debugger;
  // True if this service worker has been installed.
  bool is_installed;
  // Determines how eagerly V8 creates the code cache.
  V8CacheOptions v8_cache_options;
  // Used to set up fetch requests.
  RendererPreferences renderer_preferences;

  // Used to talk to the service worker from the browser process.
  ServiceWorker& service_worker_request;
  // S13nServiceWorker: cloned and passed to each controllee to directly
  // dispatch events from the controllees.
  ControllerServiceWorker& controller_request;
  // Information to transfer installed scripts from the browser to the renderer.
  blink.mojom.ServiceWorkerInstalledScriptsInfo? installed_scripts_info;
  // Interface for the renderer to send the status updates to the browser.
  associated EmbeddedWorkerInstanceHost instance_host;
  // Information for creating ServiceWorkerNetworkProvider on the renderer.
  ServiceWorkerProviderInfoForStartWorker provider_info;
  // Interface for the renderer to query the content settings in the browser.
  blink.mojom.WorkerContentSettingsProxy content_settings_proxy;
  // Interface for keeping track of the renderer preferences.
  RendererPreferenceWatcher& preference_watcher_request;
  // S13nServiceWorker: Used to load subresources in the service worker.
  // This allows the service worker to load chrome-extension:// URLs which
  // the renderer's default loader factory can't load.
  URLLoaderFactoryBundle? subresource_loader_factories;
};

// Holds timing information about the start worker sequence for UMA.
//
// Keep this in sync with the validation check in
// EmbeddedWorkerInstance::OnStarted.
// TODO(falken): Make a typemap just for the validation check?
struct EmbeddedWorkerStartTiming {
  // When the start worker message was received by the renderer.
  mojo_base.mojom.TimeTicks start_worker_received_time;
  // When JavaScript evaluation on the worker thread started.
  mojo_base.mojom.TimeTicks script_evaluation_start_time;
  // When JavaScript evaluation on the worker thread finished.
  mojo_base.mojom.TimeTicks script_evaluation_end_time;
};

// EmbeddedWorkerInstanceClient is the renderer-side ("Client") of
// EmbeddedWorkerInstanceHost. It allows control of a renderer-side
// embedded worker. The browser uses this interface to start, stop, and
// issue commands to the worker.
//
// This interface is the master interface of a dedicated message pipe. It has
// some interfaces associated with it, like EmbeddedWorkerInstanceHost.
interface EmbeddedWorkerInstanceClient {
  // Called back as various functions in EmbeddedWorkerInstanceHost, such
  // as OnThreadStarted(), OnStarted().
  StartWorker(EmbeddedWorkerStartParams params);
  // The response is sent back via EmbeddedWorkerInstanceHost.OnStopped().
  StopWorker();
  ResumeAfterDownload();
  AddMessageToConsole(blink.mojom.ConsoleMessageLevel level, string message);
  // Returns a DevToolsAgent interface for this embedded worker, used for
  // remote debugging. See DevToolsAgent for details.
  BindDevToolsAgent(associated blink.mojom.DevToolsAgentHost agent_host,
                    associated blink.mojom.DevToolsAgent& agent);
};

// EmbeddedWorkerInstanceHost is the browser-side ("Host") of
// EmbeddedWorkerInstanceClient. It allows control of a browser-side embedded
// worker instance. The renderer uses this interface to report embedded worker
// state back to the browser, or request termination of the worker. This
// interface is associated with the master interface
// EmbeddedWorkerInstanceClient, so it lives on the same message pipe as
// EmbeddedWorkerInstanceClient.
interface EmbeddedWorkerInstanceHost {
  // S13nServiceWorker:
  // Called when the worker requests to be terminated. The worker will request
  // to be terminated when it realizes it has been idle for some time. The
  // browser doesn't terminate the worker when there are inflight events or
  // DevTools is attached, and in that case the callback will be called with
  // false. Note that the browser can terminate the worker at any time even if
  // RequestTermination() is not called. For example, if the worker thread is
  // continuously busy and the browser's periodic ping message has been missed,
  // the browser will terminate the service worker.
  RequestTermination() => (bool will_be_terminated);

  // Tells the browser process that this service worker used |feature|, for
  // UseCounter purposes. The browser process propagates the feature usage bit
  // to all clients controlled by the service worker. See
  // https://crbug.com/376039 for background.
  // Note: Because CountFeature() is possible to be called on the main thread
  // during service worker startup and is also called on the worker thread after
  // that, we put it here rather than interface ServiceWorkerHost, so that we
  // can still keep interface ServiceWorkerHost being used solely on the worker
  // thread in the renderer process.
  CountFeature(blink.mojom.WebFeature feature);

  // The following are called during startup:
  //
  // Indicates that the worker is ready for inspection. This message is needed
  // because DevTools requires the shadow page to have been created before
  // inspecting the worker.
  OnReadyForInspection();
  // Indicates that the worker has finished loading the main script.
  //
  // This is only called for new (non-installed) workers. It's used so the
  // browser process knows it can resume the paused worker via
  // ResumeAfterDownloaded().
  OnScriptLoaded();
  // Indicates that initial JavaScript evaluation is starting. This is useful
  // for the browser process to start enforcing timeouts on script execution.
  OnScriptEvaluationStart();
  // Indicates that the worker has started. |thread_id| is the platform
  // thread id the worker runs on.
  OnStarted(blink.mojom.ServiceWorkerStartStatus status,
            int32 thread_id,
            EmbeddedWorkerStartTiming start_timing);

  // Reports that an uncaught exception occurred in the worker.
  OnReportException(mojo_base.mojom.String16 error_message, int32 line_number,
                    int32 column_number, url.mojom.Url source_url);

  // Reports that a console message was emitted to the worker's console.
  OnReportConsoleMessage(int32 source_identifier, int32 message_level,
                         mojo_base.mojom.String16 message, int32 line_number,
                         url.mojom.Url source_url);
  // Indicates that the worker has stopped.
  OnStopped();
};
