// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
module media_router.mojom;
import "components/media_router/common/mojom/logger.mojom";
import "components/media_router/common/mojom/debugger.mojom";
import "components/media_router/common/mojom/media_controller.mojom";
import "components/media_router/common/mojom/media_route_provider_id.mojom";
import "components/media_router/common/mojom/media_status.mojom";
import "components/media_router/common/mojom/route_request_result_code.mojom";
import "mojo/public/mojom/base/time.mojom";
import "mojo/public/mojom/base/values.mojom";
import "services/network/public/mojom/ip_address.mojom";
import "services/network/public/mojom/ip_endpoint.mojom";
import "third_party/blink/public/mojom/presentation/presentation.mojom";
import "url/mojom/origin.mojom";
import "url/mojom/url.mojom";
// This must stay in sync with media_router::SinkIconType and ash::SinkIconType.
enum SinkIconType {
CAST = 0,
CAST_AUDIO_GROUP = 1,
CAST_AUDIO = 2,
WIRED_DISPLAY = 6,
GENERIC = 7
};
// Represents an output sink to which media can be routed.
struct MediaSink {
// The sink identifier, e.g. "rs71w7mFzYLFlabir_qO4NHl6SUc."
string sink_id;
// The human-readable name, e.g. "Janet's Chromecast".
string name;
// The type of icon to show in the UI for this media sink.
SinkIconType icon_type;
// The ID of the MediaRouteProvider that this sink belongs to.
MediaRouteProviderId provider_id;
// This is currently only set by MediaRouter in OnSinksDiscovered().
MediaSinkExtraData? extra_data;
};
union MediaSinkExtraData {
DialMediaSink dial_media_sink;
CastMediaSink cast_media_sink;
};
struct DialMediaSink {
network.mojom.IPAddress ip_address;
// Model name of the sink, if it represents a physical device.
string model_name;
// Used for DIAL launch
url.mojom.Url app_url;
};
struct CastMediaSink {
network.mojom.IPEndPoint ip_endpoint;
// Model name of the sink, if it represents a physical device.
string model_name;
// Bit vector representing capabilities of the sink. Enum values are defined
// by CastDeviceCapability in cast_device_capability.h.
uint64 capabilities;
// ID of Cast channel opened by Media Router. The ID is defined by the
// chrome.cast.channel API.
int32 cast_channel_id;
};
enum RouteControllerType {
kNone, // No route controller.
kGeneric, // Route controller for sessions with media controls (apps).
kMirroring // Route controller for Cast mirroring and remoting sessions.
};
// MediaRoute objects contain the status and metadata of a routing
// operation.
// This struct should be kept in sync with media_route.h.
struct MediaRoute {
// The ID of this media route, e.g. "r_PR1O_blkC9dsKp-tb1ti8qurOo".
string media_route_id;
// The ID of the presentation that this route is associated with.
string presentation_id;
// The ID of the media source being sent through this media route.
// May be missing if route is not local.
string? media_source;
// The ID of sink that is rendering the media content.
string media_sink_id;
// Human readable name of the sink.
string media_sink_name;
// Human readable description of the casting activity. Examples:
// "Mirroring tab (www.example.com)", "Casting media", "Casting YouTube"
string description;
// Specifies that the route is requested locally.
bool is_local;
// The type of route controller that can be created for this route. See
// media_controller.mojom for details.
RouteControllerType controller_type;
// Set to true if this route corresponds to a local presentation.
bool is_local_presentation;
// Set to true if this route has been created by the MRP but is waiting for
// the receiver's response.
bool is_connecting;
};
struct Issue {
enum Severity {
WARNING,
NOTIFICATION
};
// If set, the ID of the route to which this issue pertains.
// If this is an empty string (default), then this is a global issue.
string route_id;
// The ID of the sink associated with this issue.
// If this is an empty string (default), then this is a global issue.
string sink_id;
Severity severity;
// Short description about the issue.
string title;
// Message about issue detail or how to handle issue.
// Messages should be suitable for end users to decide which actions to take.
string? message;
};
struct RouteMessage {
enum Type {
TEXT,
BINARY
};
// The type of this message.
Type type;
// Used when the |type| is TEXT.
string? message;
// Used when the |type| is BINARY.
array<uint8>? data;
};
// Used to pass a pair of PresentationConnection pipes as part of a route
// result. An MRP may return this as part of any route creation callback to
// allow direct communication with the controlling page.
struct RoutePresentationConnection {
// Remote to send messages to the MRP.
pending_remote<blink.mojom.PresentationConnection> connection_remote;
// Receiver which the controlling page should bind to receive messages from
// the MRP.
pending_receiver<blink.mojom.PresentationConnection> connection_receiver;
};
// State of one active Cast session.
struct CastSessionState {
// The Media Sink ID for the session.
string sink_id;
// The Cast App ID that the session is currently running.
string app_id;
// The session ID assigned by the Cast Receiver.
string session_id;
// Human readable description of the app or session, e.g. "Netflix."
string route_description;
};
// The state of the Cast Media Route Provider.
struct CastProviderState {
// Includes all sessions running on known (local network) Cast receivers.
array<CastSessionState> session_state;
};
// Returned to the Media Router to reflect the state of a single route
// provider for chrome://media-router-internals.
union ProviderState {
// The state of the Cast MRP.
CastProviderState cast_provider_state;
};
// Modeled after the MediaRouter interface defined in
// chrome/browser/media/router/media_router.h
//
// MediaRouteProvider is responsible for discovering MediaSinks, and managing
// MediaRoutes associated with them.
// A MediaRouteProvider is associated with a MediaRouter. MediaRouter issues
// commands to the MediaRouteProvider, such as observing MediaSinks or creating
// a MediaRoute. In return, the MediaRouteProvider notifies the MediaRouter when
// there are changes related to sinks or routes.
// Each MRP is used to manage one type of media sinks (e.g. the Cast MRP is used
// for CAST sinks)
// WIRED_DISPLAY, CAST and DIAL MRPs live in the browser. ANDROID_CAF is the
// Cast Application Framework based MRPs used on Android only.
interface MediaRouteProvider {
// Creates a media route from |media_source| to the sink given by |sink_id|.
//
// The presentation ID of the route created will be |presentation_id|, but it
// may be overridden by a provider implementation. The presentation ID will
// be used by the presentation API to refer to the created route.
//
// |origin| and |frame_tree_node_id| may be passed in for enforcing
// same-origin and/or same-tab scopes. Use -1 as |frame_tree_node_id| in
// cases where the request is not made on behalf of a tab.
//
// If |timeout| is positive, it will be used in place of the default timeout
// defined by Media Route Provider Manager.
//
// If the operation was successful, |route| will be defined and |error_text|
// will be null. If the operation failed, |route| will be null and
// |error_text| will be set. If |connection| is set, it should be returned to
// the presentation controller for communication with the MRP/receiver.
//
// |result_code| will be set to OK if successful, or an error code if an error
// occurred.
// TODO(crbug.com/1346066): Consolidate parameters into a struct.
// TODO(crbug.com/1351184): Make |frame_tree_node_id| optional.
CreateRoute(string media_source,
string sink_id,
string original_presentation_id,
url.mojom.Origin origin,
int32 frame_tree_node_id,
mojo_base.mojom.TimeDelta timeout) =>
(MediaRoute? route,
RoutePresentationConnection? connection,
string? error_text,
RouteRequestResultCode result_code);
// Requests a connection to an established route for |media_source| given
// by |presentation_id|.
//
// |origin| and |frame_tree_node_id| are used for validating same-origin/tab
// scopes; see CreateRoute for additional documentation.
//
// If |timeout| is positive, it will be used in place of the default timeout
// defined by Media Route Provider Manager.
//
// If the operation was successful, |route| will be defined and |error_text|
// will be null. If the operation failed, |route| will be null and
// |error_text| will be set. If |connection| is set, it should be returned to
// the presentation controller for communication with the MRP/receiver.
//
// |result_code| will be set to OK if successful, or an error code if an error
// occurred.
// TODO(crbug.com/1346066): Consolidate parameters into a struct.
// TODO(crbug.com/1351184): Make |frame_tree_node_id| optional.
JoinRoute(string media_source,
string presentation_id,
url.mojom.Origin origin,
int32 frame_tree_node_id,
mojo_base.mojom.TimeDelta timeout) =>
(MediaRoute? route,
RoutePresentationConnection? connection,
string? error_text,
RouteRequestResultCode result_code);
// Terminates the route specified by |route_id|. If the route was terminated
// successfully, |result_code| is set to OK and |error_text| is null.
// Otherwise, |result_code| is an error code and |error_text| describes the
// error.
TerminateRoute(string route_id) =>
(string? error_text, RouteRequestResultCode result_code);
// Sends |message| via the media route |media_route_id|.
// If the operation was successful, |sent| is true; otherwise it is false.
SendRouteMessage(string media_route_id, string message);
// Sends |data| via the media route |media_route_id|.
// If the operation was successful, |sent| is true; otherwise it is false.
SendRouteBinaryMessage(string media_route_id, array<uint8> data);
// Starts querying for sinks capable of displaying |media_source|. If
// |media_source| is empty, queries for all available sinks.
StartObservingMediaSinks(string media_source);
// Stops querying sinks for |media_source|.
StopObservingMediaSinks(string media_source);
// Starts reporting the state of active media routes.
StartObservingMediaRoutes();
// Indicates that a PresentationConnection that was connected to route
// |route_id| has been closed (via .close(), garbage collection or
// navigation).
DetachRoute(string route_id);
// Enables mDNS discovery. No-op if mDNS discovery is already enabled.
// Calling this will trigger a firewall prompt on Windows if there is not
// already a firewall rule for mDNS.
EnableMdnsDiscovery();
// Requests the MediaRouteProvider to update its list of media sinks.
// This is called when a user gesture occurs, and the MRP is expected to
// initiate discovery of media sinks in response.
DiscoverSinksNow();
// Binds the |media_controller| for the media route with given |route_id| to
// receive media commands, and binds the |observer| to be notified whenever
// there is a change in the status of the media route. This method can be
// called multiple times with the same |route_id| to bind multiple
// |media_controller|s and |observer|s. This method returns false if the media
// route for |route_id| does not exist or there was an error while binding the
// |media_controller|. This method must close |media_controller| in case
// of such a failure. |media_controller| becomes invalid when the media route
// is terminated by calling |TerminateRoute|.
BindMediaController(
string route_id,
pending_receiver<MediaController> media_controller,
pending_remote<MediaStatusObserver> observer) => (bool success);
// Returns the state of this Media Route Provider for debugging; returns null
// if this MRP does not report any state.
//
// Currently, only the Cast MRP returns a state value.
GetState() => (ProviderState? state);
};
// Interface for a service which observes MediaRouteProviders for state changes
// across media sources, sinks, and issues. The MediaRouter lives in the browser
// process.
interface MediaRouter {
// Registers a MediaRouteProvider with the MediaRouter.
RegisterMediaRouteProvider(MediaRouteProviderId provider_id,
pending_remote<MediaRouteProvider> media_router_provider);
// Called when a MediaRouteProvider receives a new list of |sinks|
// compatible with |media_source|. The result is only valid for |origins|. If
// |origins| is empty, the result is valid for any origin.
OnSinksReceived(MediaRouteProviderId provider_id,
string media_source,
array<MediaSink> sinks,
array<url.mojom.Origin> origins);
// Called when issues are reported for media routes.
OnIssue(Issue issue);
// Clears the top Issue if it belongs to the given sink_id.
ClearTopIssueForSink(string sink_id);
// Called when list of routes for a MediaRouteProvider has been updated.
OnRoutesUpdated(MediaRouteProviderId provider_id,
array<MediaRoute> routes);
// Called when the state of presentation connected to route |route_id| has
// changed to |state|.
OnPresentationConnectionStateChanged(
string route_id, blink.mojom.PresentationConnectionState state);
// Called when the presentation connected to route |route_id| has closed.
OnPresentationConnectionClosed(
string route_id, blink.mojom.PresentationConnectionCloseReason reason,
string message);
// Called when the a batch of messages arrives from the media sink for the
// route given by |route_id|.
// |StartListeningForRouteMessages| must be called first in order to receive
// messages.
// |route_id|: ID of route of the messages.
// |messages|: A non-empty list of messages received.
OnRouteMessagesReceived(string route_id,
array<RouteMessage> messages);
// Returns current status of media sink service in JSON format.
GetMediaSinkServiceStatus() => (string status);
// The logger can be used to add entries to logs returned by GetLogs().
GetLogger(pending_receiver<Logger> receiver);
// The debugger can be used to fetch debugging states and add debugging info
// such as mirroring stats for the current session.
GetDebugger(pending_receiver<Debugger> receiver);
// Returns a JSON array of logs collected by Media Router components.
// Serializing the logs requires allocating extra memory, so it should only be
// called under limited circumstances, such as when the user is submitting a
// feedback report.
GetLogsAsString() => (string logs);
};