| // 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. |
| |
| #ifndef COMPONENTS_MEDIA_ROUTER_BROWSER_MEDIA_ROUTER_H_ |
| #define COMPONENTS_MEDIA_ROUTER_BROWSER_MEDIA_ROUTER_H_ |
| |
| #include <stdint.h> |
| |
| #include <string> |
| #include <vector> |
| |
| #include "base/callback_list.h" |
| #include "base/functional/callback.h" |
| #include "base/time/time.h" |
| #include "base/values.h" |
| #include "build/build_config.h" |
| #include "components/keyed_service/core/keyed_service.h" |
| #include "components/media_router/browser/mirroring_media_controller_host.h" |
| #include "components/media_router/browser/presentation_connection_message_observer.h" |
| #include "components/media_router/common/media_route.h" |
| #include "components/media_router/common/media_route_provider_helper.h" |
| #include "components/media_router/common/media_sink.h" |
| #include "components/media_router/common/media_source.h" |
| #include "components/media_router/common/mojom/media_router.mojom.h" |
| #include "components/sessions/core/session_id.h" |
| #include "content/public/browser/presentation_service_delegate.h" |
| #include "extensions/buildflags/buildflags.h" |
| #include "media/base/flinging_controller.h" |
| #include "third_party/blink/public/mojom/presentation/presentation.mojom.h" |
| |
| #if !BUILDFLAG(IS_ANDROID) || BUILDFLAG(ENABLE_DESKTOP_ANDROID_EXTENSIONS) |
| #include "components/media_router/browser/logger_impl.h" |
| #include "components/media_router/browser/media_router_debugger.h" |
| #include "components/media_router/common/mojom/media_controller.mojom.h" |
| #include "mojo/public/cpp/bindings/pending_receiver.h" |
| #include "mojo/public/cpp/bindings/pending_remote.h" |
| #endif |
| |
| namespace content { |
| class WebContents; |
| } |
| |
| namespace url { |
| class Origin; |
| } // namespace url |
| |
| namespace media_router { |
| |
| class IssueManager; |
| class MediaRoutesObserver; |
| class MediaSinksObserver; |
| class PresentationConnectionStateObserver; |
| class RouteRequestResult; |
| |
| // Commandline flag to disable the default media route providers for tests that |
| // are sensitive to the presence of sinks e.g. on the local network. |
| constexpr char kDisableMediaRouteProvidersForTestSwitch[] = |
| "disable-media-route-providers-for-test"; |
| |
| // Type of callback used in |CreateRoute()| and |JoinRoute()|. Callback is |
| // invoked when the route request either succeeded or failed. |connection| is |
| // set depending on whether the MRP chooses to setup the PresentationConnections |
| // itself. |
| using MediaRouteResponseCallback = |
| base::OnceCallback<void(mojom::RoutePresentationConnectionPtr connection, |
| const RouteRequestResult& result)>; |
| |
| // An interface for handling resources related to media routing. |
| // Responsible for registering observers for receiving sink availability |
| // updates, handling route requests/responses, and operating on routes (e.g. |
| // posting messages or closing). |
| // TODO(imcheng): Reduce number of parameters by putting them into structs. |
| class MediaRouter : public KeyedService { |
| public: |
| ~MediaRouter() override = default; |
| |
| // Must be called before invoking any other method. |
| virtual void Initialize() = 0; |
| |
| // Creates a media route from |source_id| to |sink_id|. |
| // |origin| is the origin of requestor's page. |
| // |web_contents| is the WebContents of the tab in which the request was made. |
| // |origin| and |web_contents| are used for enforcing same-origin and/or |
| // same-tab scope for JoinRoute() requests. (e.g., if enforced, the page |
| // requesting JoinRoute() must have the same origin as the page that requested |
| // CreateRoute()). |
| // The caller may pass in nullptr for |web_contents| if tab is not applicable. |
| // Each callback in |callbacks| is invoked with a response indicating |
| // success or failure, in the order they are listed. |
| // If |timeout| is positive, then any un-invoked |callbacks| will be invoked |
| // with a timeout error after the timeout expires. |
| virtual void CreateRoute(const MediaSource::Id& source_id, |
| const MediaSink::Id& sink_id, |
| const url::Origin& origin, |
| content::WebContents* web_contents, |
| MediaRouteResponseCallback callback, |
| base::TimeDelta timeout) = 0; |
| |
| // Joins an existing route identified by |presentation_id|. |
| // |source|: The source to route to the existing route. |
| // |presentation_id|: Presentation ID of the existing route. |
| // |origin|, |web_contents|: Origin and WebContents of the join route request. |
| // Used for validation when enforcing same-origin and/or same-tab scope. |
| // (See CreateRoute documentation). |
| // Each callback in |callbacks| is invoked with a response indicating |
| // success or failure, in the order they are listed. |
| // If |timeout| is positive, then any un-invoked |callbacks| will be invoked |
| // with a timeout error after the timeout expires. |
| virtual void JoinRoute(const MediaSource::Id& source, |
| const std::string& presentation_id, |
| const url::Origin& origin, |
| content::WebContents* web_contents, |
| MediaRouteResponseCallback callback, |
| base::TimeDelta timeout) = 0; |
| |
| // Terminates the media route specified by |route_id|. |
| virtual void TerminateRoute(const MediaRoute::Id& route_id) = 0; |
| |
| // Detaches the media route specified by |route_id|. The request might come |
| // from the page or from an event like navigation or garbage collection. |
| virtual void DetachRoute(MediaRoute::Id route_id) = 0; |
| |
| // Posts |message| to a MediaSink connected via MediaRoute with |route_id|. |
| virtual void SendRouteMessage(const MediaRoute::Id& route_id, |
| const std::string& message) = 0; |
| |
| // Sends |data| to a MediaSink connected via MediaRoute with |route_id|. |
| // This is called for Blob / ArrayBuffer / ArrayBufferView types. |
| virtual void SendRouteBinaryMessage( |
| const MediaRoute::Id& route_id, |
| std::unique_ptr<std::vector<uint8_t>> data) = 0; |
| |
| // Notifies the Media Router that the user has taken an action involving the |
| // Media Router. This can be used to perform any initialization that is not |
| // approriate to be done at construction. |
| virtual void OnUserGesture() = 0; |
| |
| // Adds |callback| to listen for state changes for presentation connected to |
| // |route_id|. The returned subscription is owned by the caller. |callback| |
| // will be invoked whenever there are state changes, until the caller destroys |
| // the subscription. |
| virtual base::CallbackListSubscription |
| AddPresentationConnectionStateChangedCallback( |
| const MediaRoute::Id& route_id, |
| const content::PresentationConnectionStateChangedCallback& callback) = 0; |
| |
| // Returns the media routes that currently exist. To get notified whenever |
| // there is a change to the media routes, subclass MediaRoutesObserver. |
| virtual std::vector<MediaRoute> GetCurrentRoutes() const = 0; |
| |
| // Returns a controller that sends commands to media within a route, and |
| // propagates MediaStatus changes. |
| // Returns a nullptr if no controller can be be found from |route_id|. |
| virtual std::unique_ptr<media::FlingingController> GetFlingingController( |
| const MediaRoute::Id& route_id) = 0; |
| |
| #if !BUILDFLAG(IS_ANDROID) || BUILDFLAG(ENABLE_DESKTOP_ANDROID_EXTENSIONS) |
| // Returns a pointer to a controller host that sends media commands related to |
| // mirroring within a route. |
| virtual MirroringMediaControllerHost* GetMirroringMediaControllerHost( |
| const MediaRoute::Id& route_id) = 0; |
| |
| // Returns the IssueManager owned by the MediaRouter. Guaranteed to be |
| // non-null. |
| virtual IssueManager* GetIssueManager() = 0; |
| |
| // Binds |controller| for sending media commands to a route. The controller |
| // will notify |observer| whenever there is a change to the status of the |
| // media. It may invalidate bindings from previous calls to this method. |
| virtual void GetMediaController( |
| const MediaRoute::Id& route_id, |
| mojo::PendingReceiver<mojom::MediaController> controller, |
| mojo::PendingRemote<mojom::MediaStatusObserver> observer) = 0; |
| |
| // Returns logs collected from Media Router components. |
| // Used by chrome://media-router-internals. |
| virtual base::Value GetLogs() const = 0; |
| |
| // Returns media router state as a JSON string represented by base::Value. |
| // Includes known sinks and sink compatibility with media sources. |
| // Used by chrome://media-router-internals. |
| virtual base::Value::Dict GetState() const = 0; |
| |
| // Returns the media route provider state for |provider_id| via |callback|. |
| // Includes details about routes/sessions owned by the MRP. |
| // Used by chrome://media-router-internals. |
| virtual void GetProviderState( |
| mojom::MediaRouteProviderId provider_id, |
| mojom::MediaRouteProvider::GetStateCallback callback) const = 0; |
| |
| // Returns a pointer to LoggerImpl that can be used to add logging messages. |
| virtual LoggerImpl* GetLogger() = 0; |
| |
| // Returns the instance of the debugger for this MediaRouter instance. |
| virtual MediaRouterDebugger& GetDebugger() = 0; |
| #endif |
| |
| private: |
| // TODO(crbug.com/40177419): remove message observer classes and API. |
| friend class IssuesObserver; |
| friend class MediaSinksObserver; |
| friend class MediaRoutesObserver; |
| friend class PresentationConnectionStateObserver; |
| friend class PresentationConnectionMessageObserver; |
| |
| // The following functions are called by friend Observer classes above. |
| |
| // Registers |observer| with this MediaRouter. |observer| specifies a media |
| // source and will receive updates with media sinks that are compatible with |
| // that source. The initial update may happen synchronously. |
| // NOTE: This class does not assume ownership of |observer|. Callers must |
| // manage |observer| and make sure |UnregisterObserver()| is called |
| // before the observer is destroyed. |
| // It is invalid to register the same observer more than once and will result |
| // in undefined behavior. |
| // If the MRPM Host is not available, the registration request will fail |
| // immediately. |
| // The implementation can reject the request to observe in which case it will |
| // notify the caller by returning |false|. |
| virtual bool RegisterMediaSinksObserver(MediaSinksObserver* observer) = 0; |
| |
| // Removes a previously added MediaSinksObserver. |observer| will stop |
| // receiving further updates. |
| virtual void UnregisterMediaSinksObserver(MediaSinksObserver* observer) = 0; |
| |
| // Adds a MediaRoutesObserver to listen for updates on MediaRoutes. |
| // The initial update may happen synchronously. |
| // MediaRouter does not own |observer|. |UnregisterMediaRoutesObserver| should |
| // be called before |observer| is destroyed. |
| // It is invalid to register the same observer more than once and will result |
| // in undefined behavior. |
| virtual void RegisterMediaRoutesObserver(MediaRoutesObserver* observer) = 0; |
| |
| // Removes a previously added MediaRoutesObserver. |observer| will stop |
| // receiving further updates. |
| virtual void UnregisterMediaRoutesObserver(MediaRoutesObserver* observer) = 0; |
| |
| // Registers |observer| with this MediaRouter. |observer| specifies a media |
| // route and will receive messages from the MediaSink connected to the |
| // route. Note that MediaRouter does not own |observer|. |observer| should be |
| // unregistered before it is destroyed. Registering the same observer more |
| // than once will result in undefined behavior. |
| virtual void RegisterPresentationConnectionMessageObserver( |
| PresentationConnectionMessageObserver* observer) = 0; |
| |
| // Unregisters a previously registered RouteMessagesObserver. |observer| will |
| // stop receiving further updates. |
| virtual void UnregisterPresentationConnectionMessageObserver( |
| PresentationConnectionMessageObserver* observer) = 0; |
| }; |
| |
| } // namespace media_router |
| |
| #endif // COMPONENTS_MEDIA_ROUTER_BROWSER_MEDIA_ROUTER_H_ |