chromium/device/vr/public/mojom/isolated_xr_service.mojom

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

module device.mojom;

import "device/vr/public/mojom/browser_test_interfaces.mojom";
import "device/vr/public/mojom/vr_service.mojom";
import "device/vr/public/mojom/xr_device.mojom";
import "device/vr/public/mojom/xr_session.mojom";
[EnableIf=is_win]
import "gpu/ipc/common/luid.mojom";
import "gpu/ipc/common/sync_token.mojom";
import "sandbox/policy/mojom/sandbox.mojom";
import "services/viz/public/mojom/compositing/frame_sink_id.mojom";
import "services/viz/public/mojom/gpu.mojom";
import "ui/gfx/geometry/mojom/geometry.mojom";
import "ui/gfx/mojom/buffer_types.mojom";

// The XRSessionController lives in the xr runtime service, and corresponds to
// a set of the XRSession bindings.  The client is the browser process, which
// will pause or stop sessions depending events/state such as focus or other
// tabs requesting immersive sessions.
// Sessions are stopped by closing the mojo connection.
interface XRSessionController {
  // A session may be paused temporarily for example when a non-presenting
  // tab loses focus. When paused, a session will hand out null poses.
  // Eventually we may hand out poses at a throttled rate instead.
  SetFrameDataRestricted(bool restricted);
};

// The XRRuntimeEventListener lives in the xr runtime service, and allows the
// browser to listen to state changes about a device.
interface XRRuntimeEventListener {
  // A device has indicated that the visibility of the content it's displaying
  // has changed.
  OnVisibilityStateChanged(device.mojom.XRVisibilityState visibility_state);

  // Called when the device exits presentation.
  OnExitPresent();
};

struct XRRuntimeSessionOptions {
  // Represents the type of session that is being requested.
  XRSessionMode mode;

  // The below arrays combine the active required and optional features as
  // resolved by BrowserXRRuntime and VRServiceImpl.
  array<XRSessionFeature> required_features;
  array<XRSessionFeature> optional_features;

  // The following options are used for permission requests and showing module
  // install UI.
  // TODO(crbug.com/41395699): Remove these fields, and do permission checks,
  // show module install UI in the browser process before calling out to
  // devices.
  int32 render_process_id;
  int32 render_frame_id;

  array<XRTrackedImage> tracked_images;

  XRDepthOptions? depth_options;

  // ID of this request, used for tracing.
  uint64 trace_id;
};

// Used to contain all data from the session created by the runtime, and meant
// to be consumed by the browser process.
struct XRRuntimeSessionResult {
  // Used to provide the Browser with the ability to control the session created
  // by the runtime. Closing the pipe will terminate the session.
  pending_remote<XRSessionController> controller;

  // Session data needed by the renderer process. The browser process may need
  // to validate and/or manipulate this data before passing it on as part of
  // brokering the session request.
  XRSession session;

  // If the session is handling its own compositing in a way that exposes a
  // FrameSinkId, it should be set here. This allows for Tab/Screen Capture to
  // to capture this FrameSinkId, and thus the XrSession, rather than only the
  // FrameSinkId of the main contents of the WebContents.
  viz.mojom.FrameSinkId? frame_sink_id;

  // Provides a connection to the ImmersiveOverlay compositor. This is intended
  // to be used by the browser process to drive a privileged rendering path to
  // the device to show code that can be rendered on top of the page's content.
  // In some cases, this may totally obscure the page content.
  pending_remote<ImmersiveOverlay>? overlay;
};

// An XRRuntime may live in the browser process or a utility process.  The
// browser process is the client, and may in turn expose device information to
// render processes using vr_service interfaces, such as XRDevice.
interface XRRuntime {
  // Attempt to start a session. Called by the browser process, but the result
  // will probably be passed to the renderer process to allow getting data and
  // possibly submitting graphics without going through an extra IPC hop through
  // the browser process.
  RequestSession(XRRuntimeSessionOptions options) => (
                     XRRuntimeSessionResult? session);

  // Initiate shutdown of a session, and call the callback once the runtime
  // is ready for starting a new session.
  ShutdownSession() => ();

  // The browser may register for changes to a device.
  ListenToDeviceChanges(
      pending_associated_remote<XRRuntimeEventListener> listener);
};

// Information required for rendering, used by ImmersiveOverlay.
// TODO(crbug.com/40718594): This struct currently contains subset of
// data contained by XRFrameData, move it to vr_service.mojom and refactor
// XRFrameData so that it embeds this struct.
struct XRRenderInfo
{
  // The frame_id maps frame data to a frame arriving from the compositor. IDs
  // will be reused after the frame arrives from the compositor. Negative IDs
  // imply no mapping.
  int16 frame_id;

  // The pose may be null if the device lost tracking.
  VRPose? mojo_from_viewer;

  // Information about all the views in a frame. Views can appear in any order
  // so it should not be assumed the left eye comes before the right eye. It is
  // valid for the array to contain multiple views of the same eye. An example
  // of this scenario are displays that have dominant left/right eyes and inset
  // left/right eyes. In these scenarios, the dominant views comes before the
  // inset views in the array.
  array<XRView> views;
};

// Represents an overlay that the browser may show on top of or instead of WebXR
// content.  Consumed in the browser process, and implemented in the XRRuntime
// process.
interface ImmersiveOverlay {
  // Request a pose.  If there is WebXR and an overlay visible at the same time,
  // the same pose will be given to both.
  RequestNextOverlayPose() => (XRRenderInfo render_info);

  // Submit a frame to show in the headset.  Only can be called when an overlay
  // is visible.  The frame will be composited on top of WebXR content.
  // |texture| should only be used after |sync_token| has passed.
  SubmitOverlayTexture(int16 frame_id, gfx.mojom.GpuMemoryBufferHandle texture,
      gpu.mojom.SyncToken sync_token, gfx.mojom.RectF left_bounds,
      gfx.mojom.RectF right_bounds) => (bool success);

  // Allows the browser to hide WebXR content or overlays temporarily.
  SetOverlayAndWebXRVisibility(bool overlay_visible, bool webxr_visible);

  // The browser may request to be notified the browser that the current page
  // has submitted a frame.  This call returns when the current page submits a
  // frame.
  // If the current page's WebXR session is not visible because the browser has
  // made its own UI visible, the page may receive one frame's worth of pose
  // data to unblock rendering.  This allows frame-timeout UI to show while
  // still allowing a timed-out page to recover and start submitting frames.
  RequestNotificationOnWebXrSubmitted() => ();
};

// Information about a particular XR device that is available. All information
// about an available XR device should be wrapped in this struct.
struct XRDeviceData {
  // List of XR Session Features supported by the device.
  array<XRSessionFeature> supported_features;
  [EnableIf=is_win]
  // The LUID of the GPU that the device is plugged into.
  gpu.mojom.Luid? luid;
  // Indicates whether the device supports AR or not
  bool is_ar_blend_mode_supported;
};

// Notify the browser process about a set of runtimes.  The browser process
// implements this interface to be notified about runtime changes from the XR
// device service.
interface IsolatedXRRuntimeProviderClient {
  // Called when runtimes are initially enumerated, or when devices are later
  // attached and become available.
  OnDeviceAdded(pending_remote<XRRuntime> runtime,
      XRDeviceData device_data,
      device.mojom.XRDeviceId device_id);

  // Called when runtimes become unavailable - for example if the hardware is
  // disconnected or the APIs notify us that they are shutting down.
  // device_index corresponds to display_info->index for a previously added
  // device.
  OnDeviceRemoved(device.mojom.XRDeviceId device_index);

  // Called once after all the initial OnDeviceAdded calls are completed.
  // This is a signal to the browser that it knows what hardware is available,
  // and can unblock any callbacks/promises that WebXR APIs are blocked.
  OnDevicesEnumerated();
};

// Provides access to XRRuntimes.  This is implemented in the XR device service,
// and consumed by the browser.
interface IsolatedXRRuntimeProvider {
  // Register a client, and triggers OnDeviceAdded for all available runtimes,
  // followed by OnDevicesEnumerated.
  // Should only be called once.
  RequestDevices(pending_remote<IsolatedXRRuntimeProviderClient> client);
};

[EnableIf=is_win]
const sandbox.mojom.Sandbox kXrSandbox = sandbox.mojom.Sandbox.kXrCompositing;
[EnableIfNot=is_win]
const sandbox.mojom.Sandbox kXrSandbox = sandbox.mojom.Sandbox.kUtility;

// The main interface for the XR Device Service. Called from the browser
// process.
[ServiceSandbox=kXrSandbox]
interface XRDeviceService {
  // Binds a IsolatedXRRuntimeProvider pipe in the service and passes along
  // the device service host.
  BindRuntimeProvider(pending_receiver<IsolatedXRRuntimeProvider> receiver,
      pending_remote<XRDeviceServiceHost> host);

  // Binds the main testing interface pipe in the service. Only used by
  // browser tests.
  BindTestHook(pending_receiver<device_test.mojom.XRServiceTestHook> receiver);
};

// XRDeviceServiceHost is implemented in the browser process and called from
// the XR process.
interface XRDeviceServiceHost {
  // BindGpu is implemented in the browser process and allows the XR process to
  // establish a connection to the GPU process.
  BindGpu(pending_receiver<viz.mojom.Gpu> receiver);
};