| // Copyright 2015 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 media_router.mojom; |
| |
| import "chrome/common/media_router/mojo/media_controller.mojom"; |
| import "chrome/common/media_router/mojo/media_status.mojom"; |
| import "components/mirroring/mojom/mirroring_service_host.mojom"; |
| import "media/mojo/interfaces/mirror_service_remoting.mojom"; |
| import "mojo/public/mojom/base/time.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 ash.mojom.SinkIconType. |
| enum SinkIconType { |
| CAST, |
| CAST_AUDIO_GROUP, |
| CAST_AUDIO, |
| MEETING, |
| HANGOUT, |
| EDUCATION, |
| WIRED_DISPLAY, |
| GENERIC |
| }; |
| |
| // 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; |
| // Optional description of the sink. |
| // |
| // DEPRECATED. This is currently used in the Media Router UX to relay a |
| // Hangouts meeting name. It should not be used for other purposes. |
| // TODO(crbug.com/786208): Remove this at a future date when Hangouts names |
| // are no longer required. |
| string? description; |
| // Optional domain of the sink if this sink is associated with an identity. |
| string? domain; |
| // 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. |
| MediaRouteProvider.Id 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; |
| |
| // A bit vector representing capabilities of the sink. Meaning of capacity |
| // value for each bit: |
| // NONE: 0, |
| // VIDEO_OUT: 1 << 0, |
| // VIDEO_IN: 1 << 1, |
| // AUDIO_OUT: 1 << 2, |
| // AUDIO_IN: 1 << 3, |
| // DEV_MODE: 1 << 4, |
| // MULTIZONE_GROUP: 1 << 5 |
| uint8 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, |
| kGeneric, |
| kHangouts, |
| kMirroring |
| }; |
| |
| // 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 description of the casting activity. Examples: |
| // "Mirroring tab (www.example.com)", "Casting media", "Casting YouTube" |
| // |
| // TODO(crbug.com/786208): Localize this properly by passing it in a way that |
| // permits use of template strings and placeholders. |
| 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 should be displayed for |media_sink_id| in UI. |
| bool for_display; |
| // Set to true if this route was created by an incognito profile. |
| bool is_incognito; |
| // Set to true if this route corresponds to a local presentation. |
| bool is_local_presentation; |
| }; |
| |
| // Notifications or an actionable events to be shown to the user. |
| // When is_blocking is true, media router UI shows issue only: |
| // |
| // Title |
| // Message |
| // default_action_button secondary_action_button |
| // |
| // When is_blocking is false, media router UI uses banner: |
| // |
| // Title default_action_link secondary_action_link |
| // |
| // above receiver list if route_id is not provided; otherwise it is |
| // above route detail and controls. |
| struct Issue { |
| enum Severity { |
| FATAL, |
| WARNING, |
| NOTIFICATION |
| }; |
| |
| enum ActionType { |
| DISMISS, |
| LEARN_MORE |
| }; |
| |
| // 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. |
| // TODO(https://crbug.com/554646): Associate all issues with sinks. |
| string sink_id; |
| |
| Severity severity; |
| |
| // When true, the issue must be presented to the user and resolved |
| // before other actions are allowed. |
| bool is_blocking; |
| |
| // 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; |
| |
| ActionType default_action; |
| |
| array<ActionType> secondary_actions; |
| |
| // The ID of the help page to be opened if users select learn_more. |
| int32 help_page_id; |
| }; |
| |
| 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; |
| }; |
| |
| struct SinkSearchCriteria { |
| // Input to the search method which each Media Route Provider may interpret |
| // differently. |
| string input; |
| // The user's current hosted domain. |
| string domain; |
| }; |
| |
| // Keep in sync with: |
| // - RouteRequestResult::ResultCode in route_request_result.h |
| // - MediaRouteProviderResult enum in tools/metrics/histograms.xml. |
| // - mr.RouteRequestResultCode in route_request_error.js |
| // - media_router_struct_traits.h |
| enum RouteRequestResultCode { |
| UNKNOWN_ERROR, |
| OK, |
| TIMED_OUT, |
| ROUTE_NOT_FOUND, |
| SINK_NOT_FOUND, |
| INVALID_ORIGIN, |
| INCOGNITO_MISMATCH, |
| NO_SUPPORTED_PROVIDER, |
| CANCELLED, |
| ROUTE_ALREADY_EXISTS |
| // New values must be added here. |
| }; |
| |
| // Used to pass feature configuration data from the Browser to Media Route |
| // Provider. This object is used by the extension MRP only. |
| struct MediaRouteProviderConfig { |
| // If the MRP should enable DIAL discovery. |
| bool enable_dial_discovery; |
| |
| // If the MRP should enable Cast discovery. |
| bool enable_cast_discovery; |
| |
| // If the MRP should enable DIAL sink query. |
| bool enable_dial_sink_query; |
| |
| // If the MRP should enable Cast sink query. |
| bool enable_cast_sink_query; |
| |
| // If the Views dialog is being used. |
| bool use_views_dialog; |
| |
| // If Mirroring Service is being used. |
| bool use_mirroring_service; |
| }; |
| |
| // 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 { |
| // Interface pointer to send messages to the MRP. |
| blink.mojom.PresentationConnection connection_ptr; |
| |
| // Interface request which the controlling page should bind to receive |
| // messages from the MRP. |
| blink.mojom.PresentationConnection& connection_request; |
| }; |
| |
| // 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. |
| // A MediaRouteProvider may live in the Media Router component extension, or |
| // the browser (e.g. DIAL and Cast MediaRouteProviders will soon move to the |
| // browser). |
| interface MediaRouteProvider { |
| // Each MediaRouteProvider is associated with a unique ID. This enum must be |
| // kept in sync with MediaRouteProviderId in C++. |
| enum Id { |
| EXTENSION, |
| WIRED_DISPLAY, |
| CAST, |
| DIAL |
| }; |
| |
| // 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 |tab_id| may be passed in for enforcing same-origin and/or |
| // same-tab scopes. Use -1 as |tab_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 |incognito| is true, the request was made by an incognito profile. |
| // |
| // 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(btolsch): Consolidate result params into struct. |
| CreateRoute(string media_source, |
| string sink_id, |
| string original_presentation_id, |
| url.mojom.Origin origin, |
| int32 tab_id, |
| mojo_base.mojom.TimeDelta timeout, |
| bool incognito) => |
| (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 |tab_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 route request was created by an incognito profile, |
| // |incognito| must be true. |
| // |
| // 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. |
| JoinRoute(string media_source, |
| string presentation_id, |
| url.mojom.Origin origin, |
| int32 tab_id, |
| mojo_base.mojom.TimeDelta timeout, |
| bool incognito) => |
| (MediaRoute? route, |
| RoutePresentationConnection? connection, |
| string? error_text, |
| RouteRequestResultCode result_code); |
| |
| // Creates a new route for |media_source| that connects to the established |
| // route given by |route_id|. |
| // |
| // The presentation ID of the new route 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 |tab_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; see CreateRoute for additional |
| // documentation. |
| // |
| // If the route request was created by an incognito profile, |
| // |incognito| must be true. |
| // |
| // 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. |
| ConnectRouteByRouteId( |
| string media_source, |
| string route_id, |
| string presentation_id, |
| url.mojom.Origin origin, |
| int32 tab_id, |
| mojo_base.mojom.TimeDelta timeout, |
| bool incognito) => |
| (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 via |
| // OnRoutesUpdated() in the context of the |media_source|. The |
| // |media_source| represents the application interested in the media |
| // routes (usually the web page from which the content originates). |
| // If no |media_source| is given, this should be considered an |
| // observer that is not associated with a media source, and thus |
| // cannot connect to a remote route without showing a source. The |
| // |media_source| should be considered when returning joinable routes in the |
| // OnRoutesUpdated() call. If an empty |media_source| is given, there is no |
| // context in which a joinable route makes sense and therefore, there should |
| // not be any joinable routes returned in OnRoutesUpdated(). |
| // Querying will continue until StopObservingMediaRoutes() is called with |
| // the same |media_source| (even if it's an empty string). |
| StartObservingMediaRoutes(string media_source); |
| |
| // Stops querying the state of all media routes in the context of |
| // the |media_source|. StartObservingMediaRoutes() has |
| // to be called with the same |media_source| for this to have any effect even |
| // if it's empty. Thus, StartObservingMediaRoutes(media_source) must be |
| // matched with StopObservingMediaRoutes(media_source). |
| // Calling StopObservingMediaRoutes() without a media_source will stop |
| // any media routes queries associated with emtpy strings (queries |
| // that being with StartObservingMediaRoutes()). |
| StopObservingMediaRoutes(string media_source); |
| |
| // Starts listening for messages from the media sink for the route given by |
| // |route_id|. |
| // |MediaRouter::OnRouteMessagesReceived| will be invoked when a batch of |
| // messages arrives, or when there is an error. |
| // |StopListeningForRouteMessages| will stop the Media Router from receiving |
| // further messages for |route_id|. |
| StartListeningForRouteMessages(string route_id); |
| |
| // Called when there are no more listeners for messages for |route_id|. |
| StopListeningForRouteMessages(string route_id); |
| |
| // 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 the list of media sinks capable |
| // of displaying |media_source|. This call is made when a user gesture is |
| // detected, so MediaRouteProvider may treat this as a signal to take actions |
| // to become more responsive, e.g., initiate a one-off round of device |
| // discovery. |
| // TODO(https://crbug.com/698940): Rename this to OnUserGesture and remove the |
| // |media_source| parameter. |
| UpdateMediaSinks(string media_source); |
| |
| // Indicates that the Media Router is interested in finding a sink that |
| // matches |search_criteria| and is compatible with the source urn |
| // |media_source|. |search_criteria| should contain an exact copy of the user |
| // input. The user's current domain is also used to search. The domain is the |
| // hosted domain of the user's signed-in identity, or empty if the user has no |
| // domain or is not signed in. |
| SearchSinks(string sink_id, |
| string media_source, |
| SinkSearchCriteria search_criteria) => |
| (string sink_id); |
| |
| // Called when the list of MediaSinks discovered by Media Router has been |
| // updated. The sinks are supplied to the MediaRouteProvider so that they can |
| // be used for other operations, such as route creation. |
| ProvideSinks(string provider_name, array<MediaSink> sinks); |
| |
| // Creates a controller for the media route with given |route_id| and binds it |
| // to |media_controller| for receiving media commands. This method returns |
| // false if such a media route doesn't exist, a controller already exists |
| // for it, or there was an error while creating a controller. This method must |
| // close |media_controller| in case of such a failure. |media_controller| |
| // becomes invalid when the media route is terminated. The created controller |
| // is destroyed when |media_controller| becomes invalid, after which this |
| // method can be called again with the same |route_id|. This method also sets |
| // |observer| to be notified whenever there is a change in the status of the |
| // media route. |
| // TODO(takumif): Consider returning an enum instead of a bool to distinguish |
| // between error conditions for metrics/debugging. |
| CreateMediaRouteController(string route_id, |
| MediaController& media_controller, |
| MediaStatusObserver observer) => |
| (bool success); |
| }; |
| |
| // 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 { |
| |
| // Represents overall media sink availability states. |
| // UNAVAILABLE - No sinks are available. |
| // PER_SOURCE - Sinks are available, but are only compatible with specific |
| // media sources. |
| // AVAILABLE - A sink is available regardless of source. |
| enum SinkAvailability { |
| UNAVAILABLE, |
| PER_SOURCE, |
| AVAILABLE |
| }; |
| |
| // TODO(crbug.com/831416): Remove and use presentation.mojom type instead. |
| enum PresentationConnectionState { |
| CONNECTING, |
| CONNECTED, |
| CLOSED, |
| TERMINATED |
| }; |
| |
| // TODO(crbug.com/831416): Remove and use presentation.mojom type instead. |
| enum PresentationConnectionCloseReason { |
| CONNECTION_ERROR, |
| CLOSED, |
| WENT_AWAY |
| }; |
| |
| // Registers a MediaRouteProvider with the MediaRouter. |
| // Returns a string that uniquely identifies the Media Router browser |
| // process. |
| RegisterMediaRouteProvider(MediaRouteProvider.Id provider_id, |
| MediaRouteProvider media_router_provider) => |
| (string instance_id, MediaRouteProviderConfig config); |
| |
| // 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(MediaRouteProvider.Id provider_id, |
| string media_source, |
| array<MediaSink> sinks, |
| array<url.mojom.Origin> origins); |
| |
| // Called when issues are reported for media routes. |
| OnIssue(Issue issue); |
| |
| // Called when list of routes for a MediaRouteProvider has been updated in the |
| // context of the calling |media_source|. The array |joinable_route_ids| |
| // should contain route IDs of joinable routes found in the |routes| array. |
| OnRoutesUpdated(MediaRouteProvider.Id provider_id, |
| array<MediaRoute> routes, |
| string media_source, |
| array<string> joinable_route_ids); |
| |
| // Called when the availability of media sinks for a MediaRouteProvider has |
| // been updated. |
| OnSinkAvailabilityUpdated(MediaRouteProvider.Id provider_id, |
| SinkAvailability availability); |
| |
| // Called when the state of presentation connected to route |route_id| has |
| // changed to |state|. |
| OnPresentationConnectionStateChanged( |
| string route_id, PresentationConnectionState state); |
| |
| // Called when the presentation connected to route |route_id| has closed. |
| OnPresentationConnectionClosed( |
| string route_id, 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); |
| |
| // Called when a MediaRemoter for a tab with |tab_id| is started. |remoter| |
| // can be used to access the MediaRemoter to control a media remoting session |
| // and send RPC messages to the remote device. |remoting_source| is bound to |
| // receive the updates/messages from MediaRemoter. |
| OnMediaRemoterCreated(int32 tab_id, media.mojom.MirrorServiceRemoter remoter, |
| media.mojom.MirrorServiceRemotingSource& remoting_source); |
| |
| // Returns current status of media sink service in JSON format. |
| GetMediaSinkServiceStatus() => (string status); |
| |
| // Called to get a mirroring.mojom.MirroringServiceHost. These APIs are used |
| // by Media Router extension to start mirroring through the mirroring service. |
| // TODO(http://crbug.com/809249): Remove these APIs when native Cast MRP with |
| // mirroring support is rolled out. |
| GetMirroringServiceHostForTab(int32 target_tab_id, |
| mirroring.mojom.MirroringServiceHost& request); |
| GetMirroringServiceHostForDesktop( |
| int32 initiator_tab_id, // The tab used to register the stream. |
| string desktop_stream_id, |
| mirroring.mojom.MirroringServiceHost& request); |
| GetMirroringServiceHostForOffscreenTab( |
| url.mojom.Url presentation_url, |
| string presentation_id, |
| mirroring.mojom.MirroringServiceHost& request); |
| }; |