1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CHROME_BROWSER_UI_WEBUI_MEDIA_ROUTER_MEDIA_ROUTER_UI_H_
6 #define CHROME_BROWSER_UI_WEBUI_MEDIA_ROUTER_MEDIA_ROUTER_UI_H_
12 #include "base/gtest_prod_util.h"
13 #include "base/macros.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/memory/weak_ptr.h"
16 #include "chrome/browser/media/router/issue.h"
17 #include "chrome/browser/media/router/media_source.h"
18 #include "chrome/browser/media/router/presentation_service_delegate_impl.h"
19 #include "chrome/browser/ui/webui/constrained_web_dialog_ui.h"
20 #include "chrome/browser/ui/webui/media_router/media_cast_mode.h"
21 #include "chrome/browser/ui/webui/media_router/media_sink_with_cast_modes.h"
22 #include "chrome/browser/ui/webui/media_router/query_result_manager.h"
23 #include "content/public/browser/web_ui_data_source.h"
27 } // namespace content
29 namespace media_router
{
34 class MediaRouterDialogCallbacks
;
35 class MediaRouterMojoImpl
;
36 class MediaRouterWebUIMessageHandler
;
37 class MediaRoutesObserver
;
39 class MediaSinksObserver
;
40 class CreatePresentationSessionRequest
;
42 // Implements the chrome://media-router user interface.
44 : public ConstrainedWebDialogUI
,
45 public QueryResultManager::Observer
,
46 public PresentationServiceDelegateImpl::DefaultMediaSourceObserver
{
48 // |web_ui| owns this object and is used to initialize the base class.
49 explicit MediaRouterUI(content::WebUI
* web_ui
);
50 ~MediaRouterUI() override
;
52 // Initializes internal state (e.g. starts listening for MediaSinks) for
53 // targeting the default MediaSource (if any) of the initiator tab that owns
54 // |delegate|, as well as mirroring sources of that tab.
55 // The contents of the UI will change as the default MediaSource changes.
56 // If there is a default MediaSource, then DEFAULT MediaCastMode will be
57 // added to |cast_modes_|.
58 // Init* methods can only be called once.
59 // |delegate|: PresentationServiceDelegateImpl of the initiator tab.
61 // TODO(imcheng): Replace use of impl with an intermediate abstract
63 void InitWithDefaultMediaSource(
64 const base::WeakPtr
<PresentationServiceDelegateImpl
>& delegate
);
66 // Initializes internal state targeting the presentation specified in
67 // |request|. Also sets up mirroring sources based on |initiator|.
68 // This is different from |InitWithDefaultMediaSource| in that it does not
69 // listen for default media source changes, as the UI is fixed to the source
71 // Init* methods can only be called once.
72 // |initiator|: Reference to the WebContents that initiated the dialog.
74 // |delegate|: PresentationServiceDelegateImpl of the initiator tab.
76 // |presentation_request|: The presentation request. This instance will take
77 // ownership of it. Must not be null.
78 void InitWithPresentationSessionRequest(
79 content::WebContents
* initiator
,
80 const base::WeakPtr
<PresentationServiceDelegateImpl
>& delegate
,
81 scoped_ptr
<CreatePresentationSessionRequest
> presentation_request
);
83 // Closes the media router UI.
86 // Notifies this instance that the UI has been initialized.
89 // Requests a route be created from the source determined by the preferred
90 // MediaCastMode, to the sink given by |sink_id|.
91 // The preferred cast mode is determined from the set of currently supported
92 // cast modes in |cast_modes_|.
93 // Returns false if unable to request the route.
94 // |OnRouteResponseReceived()| will be invoked when the route request
96 bool CreateRoute(const MediaSink::Id
& sink_id
);
98 // Requests a route be created from the source mapped to
99 // |cast_mode_override|, to the sink given by |sink_id|.
100 // Returns true if a route request is successfully submitted.
101 bool CreateRouteWithCastModeOverride(const MediaSink::Id
& sink_id
,
102 MediaCastMode cast_mode_override
);
104 // Calls MediaRouter to close the given route.
105 void CloseRoute(const MediaRoute::Id
& route_id
);
107 // Calls MediaRouter to clear the given issue.
108 void ClearIssue(const Issue::Id
& issue_id
);
110 // Returns the header text that should be displayed in the UI when it is
111 // initially loaded. The header text is determined by the preferred cast mode.
112 std::string
GetInitialHeaderText() const;
114 // Returns the tooltip text for the header that should be displayed
115 // in the UI when it is initially loaded. At present, this text is
116 // just the full hostname of the current site.
117 std::string
GetInitialHeaderTextTooltip() const;
119 // Returns the hostname of the default source's parent frame URL.
120 std::string
GetFrameURLHost() const;
121 bool has_pending_route_request() const { return has_pending_route_request_
; }
122 const GURL
& frame_url() const { return frame_url_
; }
123 const std::vector
<MediaSinkWithCastModes
>& sinks() const { return sinks_
; }
124 const std::vector
<MediaRoute
>& routes() const { return routes_
; }
125 const std::set
<MediaCastMode
>& cast_modes() const { return cast_modes_
; }
126 const content::WebContents
* initiator() const { return initiator_
; }
128 // Marked virtual for tests.
129 virtual const std::string
& GetRouteProviderExtensionId() const;
132 FRIEND_TEST_ALL_PREFIXES(MediaRouterUITest
,
133 UIMediaRoutesObserverFiltersNonDisplayRoutes
);
135 class UIIssuesObserver
;
136 class UIMediaRoutesObserver
: public MediaRoutesObserver
{
138 using RoutesUpdatedCallback
=
139 base::Callback
<void(const std::vector
<MediaRoute
>&)>;
140 UIMediaRoutesObserver(MediaRouter
* router
,
141 const RoutesUpdatedCallback
& callback
);
142 ~UIMediaRoutesObserver() override
;
144 // MediaRoutesObserver
145 void OnRoutesUpdated(const std::vector
<MediaRoute
>& routes
) override
;
148 // Callback to the owning MediaRouterUI instance.
149 RoutesUpdatedCallback callback_
;
151 DISALLOW_COPY_AND_ASSIGN(UIMediaRoutesObserver
);
154 // QueryResultManager::Observer
155 void OnResultsUpdated(
156 const std::vector
<MediaSinkWithCastModes
>& sinks
) override
;
158 // Called by |issues_observer_| when the top issue has changed.
159 // If the UI is already initialized, notifies |handler_| to update the UI.
160 // Ignored if the UI is not yet initialized.
161 void SetIssue(const Issue
* issue
);
163 // Called by |routes_observer_| when the set of active routes has changed.
164 void OnRoutesUpdated(const std::vector
<MediaRoute
>& routes
);
166 // Callback passed to MediaRouter to receive response to route creation
168 void OnRouteResponseReceived(const MediaSink::Id
& sink_id
,
169 const MediaRoute
* route
,
170 const std::string
& presentation_id
,
171 const std::string
& error
);
173 bool DoCreateRoute(const MediaSink::Id
& sink_id
, MediaCastMode cast_mode
);
175 // Sets the source host name to be displayed in the UI.
176 // Gets cast modes from |query_result_manager_| and forwards it to UI.
177 // One of the Init* functions must have been called before.
178 void UpdateSourceHostAndCastModes(const GURL
& frame_url
);
180 // Initializes the dialog with mirroring sources derived from |initiator|,
181 // and optional |default_source| and |default_frame_url| if any.
182 void InitCommon(content::WebContents
* initiator
,
183 const MediaSource
& default_source
,
184 const GURL
& default_frame_url
);
186 // PresentationServiceDelegateImpl::DefaultMediaSourceObserver
187 void OnDefaultMediaSourceChanged(const MediaSource
& source
,
188 const GURL
& frame_url
) override
;
190 // Owned by the |web_ui| passed in the ctor, and guaranteed to be deleted
191 // only after it has deleted |this|.
192 MediaRouterWebUIMessageHandler
* handler_
;
194 // These are non-null while this instance is registered to receive
195 // updates from them.
196 scoped_ptr
<IssuesObserver
> issues_observer_
;
197 scoped_ptr
<MediaRoutesObserver
> routes_observer_
;
199 // Set to true by |handler_| when the UI has been initialized.
200 bool ui_initialized_
;
202 // Set to |true| if there is a pending route request for this UI.
203 bool has_pending_route_request_
;
205 bool requesting_route_for_default_source_
;
207 std::vector
<MediaSinkWithCastModes
> sinks_
;
208 std::vector
<MediaRoute
> routes_
;
209 CastModeSet cast_modes_
;
212 scoped_ptr
<QueryResultManager
> query_result_manager_
;
214 // If set, then the result of the next presentation route request will
215 // be handled by this object.
216 scoped_ptr
<CreatePresentationSessionRequest
> presentation_request_
;
218 // It's possible for PresentationServiceDelegateImpl to be destroyed before
220 // (e.g. if a tab with the UI open is closed, then the tab WebContents will
221 // be destroyed first momentarily before the UI WebContents).
222 // Holding a WeakPtr to PresentationServiceDelegateImpl is the cleanest way to
224 // TODO(imcheng): hold a weak ptr to an abstract type instead.
225 base::WeakPtr
<PresentationServiceDelegateImpl
> presentation_service_delegate_
;
227 content::WebContents
* initiator_
;
229 // Pointer to the MediaRouter for this instance's BrowserContext.
230 MediaRouterMojoImpl
* router_
;
232 // NOTE: Weak pointers must be invalidated before all other member variables.
233 // Therefore |weak_factory_| must be placed at the end.
234 base::WeakPtrFactory
<MediaRouterUI
> weak_factory_
;
236 DISALLOW_COPY_AND_ASSIGN(MediaRouterUI
);
239 } // namespace media_router
241 #endif // CHROME_BROWSER_UI_WEBUI_MEDIA_ROUTER_MEDIA_ROUTER_UI_H_