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 add the given issue.
108 void AddIssue(const Issue
& issue
);
110 // Calls MediaRouter to clear the given issue.
111 void ClearIssue(const Issue::Id
& issue_id
);
113 // Returns the header text that should be displayed in the UI when it is
114 // initially loaded. The header text is determined by the preferred cast mode.
115 std::string
GetInitialHeaderText() const;
117 // Returns the tooltip text for the header that should be displayed
118 // in the UI when it is initially loaded. At present, this text is
119 // just the full hostname of the current site.
120 std::string
GetInitialHeaderTextTooltip() const;
122 // Returns the hostname of the default source's parent frame URL.
123 std::string
GetFrameURLHost() const;
124 bool has_pending_route_request() const { return has_pending_route_request_
; }
125 const GURL
& frame_url() const { return frame_url_
; }
126 const std::vector
<MediaSinkWithCastModes
>& sinks() const { return sinks_
; }
127 const std::vector
<MediaRoute
>& routes() const { return routes_
; }
128 const std::set
<MediaCastMode
>& cast_modes() const { return cast_modes_
; }
129 const content::WebContents
* initiator() const { return initiator_
; }
131 // Marked virtual for tests.
132 virtual const std::string
& GetRouteProviderExtensionId() const;
135 FRIEND_TEST_ALL_PREFIXES(MediaRouterUITest
,
136 UIMediaRoutesObserverFiltersNonDisplayRoutes
);
138 class UIIssuesObserver
;
139 class UIMediaRoutesObserver
: public MediaRoutesObserver
{
141 using RoutesUpdatedCallback
=
142 base::Callback
<void(const std::vector
<MediaRoute
>&)>;
143 UIMediaRoutesObserver(MediaRouter
* router
,
144 const RoutesUpdatedCallback
& callback
);
145 ~UIMediaRoutesObserver() override
;
147 // MediaRoutesObserver
148 void OnRoutesUpdated(const std::vector
<MediaRoute
>& routes
) override
;
151 // Callback to the owning MediaRouterUI instance.
152 RoutesUpdatedCallback callback_
;
154 DISALLOW_COPY_AND_ASSIGN(UIMediaRoutesObserver
);
157 // QueryResultManager::Observer
158 void OnResultsUpdated(
159 const std::vector
<MediaSinkWithCastModes
>& sinks
) override
;
161 // Called by |issues_observer_| when the top issue has changed.
162 // If the UI is already initialized, notifies |handler_| to update the UI.
163 // Ignored if the UI is not yet initialized.
164 void SetIssue(const Issue
* issue
);
166 // Called by |routes_observer_| when the set of active routes has changed.
167 void OnRoutesUpdated(const std::vector
<MediaRoute
>& routes
);
169 // Callback passed to MediaRouter to receive response to route creation
171 void OnRouteResponseReceived(const MediaSink::Id
& sink_id
,
172 const MediaRoute
* route
,
173 const std::string
& presentation_id
,
174 const std::string
& error
);
176 bool DoCreateRoute(const MediaSink::Id
& sink_id
, MediaCastMode cast_mode
);
178 // Sets the source host name to be displayed in the UI.
179 // Gets cast modes from |query_result_manager_| and forwards it to UI.
180 // One of the Init* functions must have been called before.
181 void UpdateSourceHostAndCastModes(const GURL
& frame_url
);
183 // Initializes the dialog with mirroring sources derived from |initiator|,
184 // and optional |default_source| and |default_frame_url| if any.
185 void InitCommon(content::WebContents
* initiator
,
186 const MediaSource
& default_source
,
187 const GURL
& default_frame_url
);
189 // PresentationServiceDelegateImpl::DefaultMediaSourceObserver
190 void OnDefaultMediaSourceChanged(const MediaSource
& source
,
191 const GURL
& frame_url
) override
;
193 // Owned by the |web_ui| passed in the ctor, and guaranteed to be deleted
194 // only after it has deleted |this|.
195 MediaRouterWebUIMessageHandler
* handler_
;
197 // These are non-null while this instance is registered to receive
198 // updates from them.
199 scoped_ptr
<IssuesObserver
> issues_observer_
;
200 scoped_ptr
<MediaRoutesObserver
> routes_observer_
;
202 // Set to true by |handler_| when the UI has been initialized.
203 bool ui_initialized_
;
205 // Set to |true| if there is a pending route request for this UI.
206 bool has_pending_route_request_
;
208 bool requesting_route_for_default_source_
;
210 std::vector
<MediaSinkWithCastModes
> sinks_
;
211 std::vector
<MediaRoute
> routes_
;
212 CastModeSet cast_modes_
;
215 scoped_ptr
<QueryResultManager
> query_result_manager_
;
217 // If set, then the result of the next presentation route request will
218 // be handled by this object.
219 scoped_ptr
<CreatePresentationSessionRequest
> presentation_request_
;
221 // It's possible for PresentationServiceDelegateImpl to be destroyed before
223 // (e.g. if a tab with the UI open is closed, then the tab WebContents will
224 // be destroyed first momentarily before the UI WebContents).
225 // Holding a WeakPtr to PresentationServiceDelegateImpl is the cleanest way to
227 // TODO(imcheng): hold a weak ptr to an abstract type instead.
228 base::WeakPtr
<PresentationServiceDelegateImpl
> presentation_service_delegate_
;
230 content::WebContents
* initiator_
;
232 // Pointer to the MediaRouter for this instance's BrowserContext.
233 MediaRouterMojoImpl
* router_
;
235 // NOTE: Weak pointers must be invalidated before all other member variables.
236 // Therefore |weak_factory_| must be placed at the end.
237 base::WeakPtrFactory
<MediaRouterUI
> weak_factory_
;
239 DISALLOW_COPY_AND_ASSIGN(MediaRouterUI
);
242 } // namespace media_router
244 #endif // CHROME_BROWSER_UI_WEBUI_MEDIA_ROUTER_MEDIA_ROUTER_UI_H_