Add ICU message format support
[chromium-blink-merge.git] / chrome / browser / ui / webui / media_router / media_router_dialog_controller_impl.cc
bloba47ac8436f96d5ef1e8102363361c7462f08dd08
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 #include "chrome/browser/ui/webui/media_router/media_router_dialog_controller_impl.h"
7 #include <string>
8 #include <vector>
10 #include "chrome/browser/media/router/presentation_service_delegate_impl.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/ui/webui/constrained_web_dialog_ui.h"
13 #include "chrome/browser/ui/webui/media_router/media_router_ui.h"
14 #include "chrome/common/url_constants.h"
15 #include "components/web_modal/web_contents_modal_dialog_host.h"
16 #include "content/public/browser/navigation_controller.h"
17 #include "content/public/browser/navigation_details.h"
18 #include "content/public/browser/navigation_entry.h"
19 #include "content/public/browser/render_frame_host.h"
20 #include "content/public/browser/render_process_host.h"
21 #include "content/public/browser/render_view_host.h"
22 #include "ui/web_dialogs/web_dialog_delegate.h"
23 #include "ui/web_dialogs/web_dialog_web_contents_delegate.h"
24 #include "url/gurl.h"
26 DEFINE_WEB_CONTENTS_USER_DATA_KEY(
27 media_router::MediaRouterDialogControllerImpl);
29 using content::LoadCommittedDetails;
30 using content::NavigationController;
31 using content::WebContents;
32 using content::WebUIMessageHandler;
33 using ui::WebDialogDelegate;
35 namespace {
36 const int kMaxHeight = 260;
37 #if !defined(OS_MACOSX)
38 const int kMinHeight = 130;
39 #endif // !defined(OS_MACOSX)
40 const int kWidth = 340;
43 namespace media_router {
45 namespace {
47 // WebDialogDelegate that specifies what the media router dialog
48 // will look like.
49 class MediaRouterDialogDelegate : public WebDialogDelegate {
50 public:
51 MediaRouterDialogDelegate() {}
52 ~MediaRouterDialogDelegate() override {}
54 // WebDialogDelegate implementation.
55 ui::ModalType GetDialogModalType() const override {
56 // Not used, returning dummy value.
57 return ui::MODAL_TYPE_WINDOW;
60 base::string16 GetDialogTitle() const override {
61 return base::string16();
64 GURL GetDialogContentURL() const override {
65 return GURL(chrome::kChromeUIMediaRouterURL);
68 void GetWebUIMessageHandlers(
69 std::vector<WebUIMessageHandler*>* handlers) const override {
70 // MediaRouterUI adds its own message handlers.
73 void GetDialogSize(gfx::Size* size) const override;
75 std::string GetDialogArgs() const override {
76 return std::string();
79 void OnDialogClosed(const std::string& json_retval) override {
80 // We don't delete |this| here because this class is owned
81 // by ConstrainedWebDialogDelegate.
84 void OnCloseContents(WebContents* source, bool* out_close_dialog) override {
85 if (out_close_dialog)
86 *out_close_dialog = true;
89 bool ShouldShowDialogTitle() const override {
90 return false;
93 private:
94 DISALLOW_COPY_AND_ASSIGN(MediaRouterDialogDelegate);
97 void MediaRouterDialogDelegate::GetDialogSize(gfx::Size* size) const {
98 DCHECK(size);
99 // TODO(apacible): Remove after autoresizing is implemented for OSX.
100 #if defined(OS_MACOSX)
101 *size = gfx::Size(kWidth, kMaxHeight);
102 #else
103 // size is not used because the dialog is auto-resizeable.
104 *size = gfx::Size();
105 #endif
108 } // namespace
110 // static
111 MediaRouterDialogControllerImpl*
112 MediaRouterDialogControllerImpl::GetOrCreateForWebContents(
113 WebContents* web_contents) {
114 DCHECK(web_contents);
115 // This call does nothing if the controller already exists.
116 MediaRouterDialogControllerImpl::CreateForWebContents(web_contents);
117 return MediaRouterDialogControllerImpl::FromWebContents(web_contents);
120 class MediaRouterDialogControllerImpl::DialogWebContentsObserver
121 : public content::WebContentsObserver {
122 public:
123 DialogWebContentsObserver(
124 WebContents* web_contents,
125 MediaRouterDialogControllerImpl* dialog_controller)
126 : content::WebContentsObserver(web_contents),
127 dialog_controller_(dialog_controller) {
130 private:
131 void WebContentsDestroyed() override {
132 // The dialog is already closed. No need to call Close() again.
133 // NOTE: |this| is deleted after Reset() returns.
134 dialog_controller_->Reset();
137 void NavigationEntryCommitted(const LoadCommittedDetails& load_details)
138 override {
139 dialog_controller_->OnDialogNavigated(load_details);
142 void RenderProcessGone(base::TerminationStatus status) override {
143 // NOTE: |this| is deleted after CloseMediaRouterDialog() returns.
144 dialog_controller_->CloseMediaRouterDialog();
147 MediaRouterDialogControllerImpl* const dialog_controller_;
150 MediaRouterDialogControllerImpl::MediaRouterDialogControllerImpl(
151 WebContents* web_contents)
152 : MediaRouterDialogController(web_contents),
153 media_router_dialog_pending_(false) {
156 MediaRouterDialogControllerImpl::~MediaRouterDialogControllerImpl() {
159 WebContents* MediaRouterDialogControllerImpl::GetMediaRouterDialog() const {
160 DCHECK(thread_checker_.CalledOnValidThread());
161 return dialog_observer_.get() ? dialog_observer_->web_contents() : nullptr;
164 bool MediaRouterDialogControllerImpl::IsShowingMediaRouterDialog() const {
165 return GetMediaRouterDialog() != nullptr;
168 void MediaRouterDialogControllerImpl::CloseMediaRouterDialog() {
169 WebContents* media_router_dialog = GetMediaRouterDialog();
170 if (!media_router_dialog)
171 return;
173 content::WebUI* web_ui = media_router_dialog->GetWebUI();
174 if (web_ui) {
175 MediaRouterUI* media_router_ui =
176 static_cast<MediaRouterUI*>(web_ui->GetController());
177 if (media_router_ui)
178 media_router_ui->Close();
182 void MediaRouterDialogControllerImpl::CreateMediaRouterDialog() {
183 DCHECK(!dialog_observer_.get());
185 Profile* profile =
186 Profile::FromBrowserContext(initiator()->GetBrowserContext());
187 DCHECK(profile);
189 WebDialogDelegate* web_dialog_delegate = new MediaRouterDialogDelegate;
191 // |web_dialog_delegate|'s owner is |constrained_delegate|.
192 // |constrained_delegate| is owned by the parent |views::View|.
193 // TODO(apacible): Remove after autoresizing is implemented for OSX.
194 #if defined(OS_MACOSX)
195 ConstrainedWebDialogDelegate* constrained_delegate =
196 ShowConstrainedWebDialog(profile, web_dialog_delegate, initiator());
197 #else
198 // TODO(apacible): Adjust min and max sizes based on new WebUI design.
199 gfx::Size min_size = gfx::Size(kWidth, kMinHeight);
200 gfx::Size max_size = gfx::Size(kWidth, kMaxHeight);
202 // |ShowConstrainedWebDialogWithAutoResize()| will end up creating
203 // ConstrainedWebDialogDelegateViewViews containing a WebContents containing
204 // the MediaRouterUI, using the provided |web_dialog_delegate|. Then, the
205 // view is shown as a modal dialog constrained to the |initiator| WebContents.
206 // The dialog will resize between the |min_size| and |max_size| bounds based
207 // on the currently rendered contents.
208 ConstrainedWebDialogDelegate* constrained_delegate =
209 ShowConstrainedWebDialogWithAutoResize(
210 profile, web_dialog_delegate, initiator(), min_size, max_size);
211 #endif
213 WebContents* media_router_dialog = constrained_delegate->GetWebContents();
215 media_router_dialog_pending_ = true;
217 dialog_observer_.reset(new DialogWebContentsObserver(
218 media_router_dialog, this));
221 void MediaRouterDialogControllerImpl::Reset() {
222 MediaRouterDialogController::Reset();
223 dialog_observer_.reset();
226 void MediaRouterDialogControllerImpl::OnDialogNavigated(
227 const content::LoadCommittedDetails& details) {
228 DCHECK(thread_checker_.CalledOnValidThread());
229 WebContents* media_router_dialog = GetMediaRouterDialog();
230 CHECK(media_router_dialog);
231 ui::PageTransition transition_type = details.entry->GetTransitionType();
232 content::NavigationType nav_type = details.type;
234 // New |media_router_dialog| is created.
235 DCHECK(media_router_dialog_pending_);
236 DCHECK(transition_type == ui::PAGE_TRANSITION_AUTO_TOPLEVEL &&
237 nav_type == content::NAVIGATION_TYPE_NEW_PAGE)
238 << "transition_type: " << transition_type << ", "
239 << "nav_type: " << nav_type;
241 media_router_dialog_pending_ = false;
243 PopulateDialog(media_router_dialog);
246 void MediaRouterDialogControllerImpl::PopulateDialog(
247 content::WebContents* media_router_dialog) {
248 DCHECK(thread_checker_.CalledOnValidThread());
249 DCHECK(media_router_dialog);
250 if (!initiator() || !media_router_dialog->GetWebUI()) {
251 Reset();
252 return;
255 MediaRouterUI* media_router_ui = static_cast<MediaRouterUI*>(
256 media_router_dialog->GetWebUI()->GetController());
257 DCHECK(media_router_ui);
258 if (!media_router_ui) {
259 Reset();
260 return;
263 scoped_ptr<CreatePresentationSessionRequest> presentation_request(
264 PassPresentationRequest());
265 // TODO(imcheng): Don't create PresentationServiceDelegateImpl if it doesn't
266 // exist (crbug.com/508695).
267 base::WeakPtr<PresentationServiceDelegateImpl> delegate =
268 PresentationServiceDelegateImpl::GetOrCreateForWebContents(initiator())
269 ->GetWeakPtr();
270 if (!presentation_request.get()) {
271 media_router_ui->InitWithDefaultMediaSource(delegate);
272 } else {
273 media_router_ui->InitWithPresentationSessionRequest(
274 initiator(), delegate, presentation_request.Pass());
278 } // namespace media_router