Don't show supervised user as "already on this device" while they're being imported.
[chromium-blink-merge.git] / chrome / browser / ui / webui / media_router / media_router_dialog_controller.cc
blob1265f53dd411b25d3d72ea2e29ef12ad56b4427a
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.h"
7 #include <string>
8 #include <vector>
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/ui/webui/constrained_web_dialog_ui.h"
12 #include "chrome/browser/ui/webui/media_router/media_router_ui.h"
13 #include "chrome/common/url_constants.h"
14 #include "components/web_modal/web_contents_modal_dialog_host.h"
15 #include "content/public/browser/browser_thread.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 "content/public/browser/web_contents.h"
23 #include "content/public/browser/web_contents_delegate.h"
24 #include "ui/web_dialogs/web_dialog_delegate.h"
25 #include "ui/web_dialogs/web_dialog_web_contents_delegate.h"
26 #include "url/gurl.h"
28 DEFINE_WEB_CONTENTS_USER_DATA_KEY(media_router::MediaRouterDialogController);
30 using content::LoadCommittedDetails;
31 using content::NavigationController;
32 using content::WebContents;
33 using content::WebUIMessageHandler;
34 using ui::WebDialogDelegate;
36 namespace media_router {
38 namespace {
40 // WebDialogDelegate that specifies what the media router dialog
41 // will look like.
42 class MediaRouterDialogDelegate : public WebDialogDelegate {
43 public:
44 MediaRouterDialogDelegate() {}
45 ~MediaRouterDialogDelegate() override {}
47 // WebDialogDelegate implementation.
48 ui::ModalType GetDialogModalType() const override {
49 // Not used, returning dummy value.
50 return ui::MODAL_TYPE_WINDOW;
53 base::string16 GetDialogTitle() const override {
54 return base::string16();
57 GURL GetDialogContentURL() const override {
58 return GURL(chrome::kChromeUIMediaRouterURL);
61 void GetWebUIMessageHandlers(
62 std::vector<WebUIMessageHandler*>* handlers) const override {
63 // MediaRouterUI adds its own message handlers.
66 void GetDialogSize(gfx::Size* size) const override;
68 std::string GetDialogArgs() const override {
69 return std::string();
72 void OnDialogClosed(const std::string& json_retval) override {
73 // We don't delete |this| here because this class is owned
74 // by ConstrainedWebDialogDelegate.
77 void OnCloseContents(WebContents* source, bool* out_close_dialog) override {
78 if (out_close_dialog)
79 *out_close_dialog = true;
82 bool ShouldShowDialogTitle() const override {
83 return false;
86 private:
87 DISALLOW_COPY_AND_ASSIGN(MediaRouterDialogDelegate);
90 void MediaRouterDialogDelegate::GetDialogSize(gfx::Size* size) const {
91 DCHECK(size);
92 // TODO(apacible): Remove after autoresizing is implemented for OSX.
93 #if defined(OS_MACOSX)
94 *size = gfx::Size(330, 400);
95 #else
96 // size is not used because the dialog is auto-resizeable.
97 *size = gfx::Size();
98 #endif
101 } // namespace
103 class MediaRouterDialogController::DialogWebContentsObserver
104 : public content::WebContentsObserver {
105 public:
106 DialogWebContentsObserver(
107 WebContents* web_contents,
108 MediaRouterDialogController* dialog_controller)
109 : content::WebContentsObserver(web_contents),
110 dialog_controller_(dialog_controller) {
113 private:
114 void WebContentsDestroyed() override {
115 // The dialog is already closed. No need to call Close() again.
116 // NOTE: |this| is deleted after RemoveObservers() returns.
117 dialog_controller_->RemoveObservers();
120 void NavigationEntryCommitted(const LoadCommittedDetails& load_details)
121 override {
122 dialog_controller_->OnDialogNavigated(load_details);
125 void RenderProcessGone(base::TerminationStatus status) override {
126 // NOTE: |this| is deleted after CloseMediaRouterDialog() returns.
127 dialog_controller_->CloseMediaRouterDialog();
130 MediaRouterDialogController* const dialog_controller_;
133 class MediaRouterDialogController::InitiatorWebContentsObserver
134 : public content::WebContentsObserver {
135 public:
136 InitiatorWebContentsObserver(
137 WebContents* web_contents,
138 MediaRouterDialogController* dialog_controller)
139 : content::WebContentsObserver(web_contents),
140 dialog_controller_(dialog_controller) {
143 private:
144 void WebContentsDestroyed() override {
145 // NOTE: |this| is deleted after CloseMediaRouterDialog() returns.
146 dialog_controller_->CloseMediaRouterDialog();
149 void NavigationEntryCommitted(const LoadCommittedDetails& load_details)
150 override {
151 // NOTE: |this| is deleted after CloseMediaRouterDialog() returns.
152 dialog_controller_->CloseMediaRouterDialog();
155 void RenderProcessGone(base::TerminationStatus status) override {
156 // NOTE: |this| is deleted after CloseMediaRouterDialog() returns.
157 dialog_controller_->CloseMediaRouterDialog();
160 MediaRouterDialogController* const dialog_controller_;
163 MediaRouterDialogController::MediaRouterDialogController(
164 WebContents* web_contents)
165 : initiator_(web_contents),
166 media_router_dialog_pending_(false) {
167 DCHECK(initiator_);
168 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
171 MediaRouterDialogController::~MediaRouterDialogController() {
172 DCHECK(thread_checker_.CalledOnValidThread());
175 WebContents* MediaRouterDialogController::ShowMediaRouterDialog() {
176 DCHECK(thread_checker_.CalledOnValidThread());
178 // Get the media router dialog for |initiator|, or create a new dialog
179 // if not found.
180 WebContents* media_router_dialog = GetMediaRouterDialog();
181 if (!media_router_dialog)
182 return CreateMediaRouterDialog();
184 // Show the initiator holding the existing media router dialog.
185 initiator_->GetDelegate()->ActivateContents(initiator_);
186 return media_router_dialog;
189 WebContents* MediaRouterDialogController::GetMediaRouterDialog() const {
190 DCHECK(thread_checker_.CalledOnValidThread());
191 return dialog_observer_.get() ? dialog_observer_->web_contents() : nullptr;
194 void MediaRouterDialogController::CloseMediaRouterDialog() {
195 DCHECK(thread_checker_.CalledOnValidThread());
196 DCHECK(initiator_observer_.get());
197 WebContents* media_router_dialog = GetMediaRouterDialog();
198 CHECK(media_router_dialog);
199 RemoveObservers();
201 content::WebUI* web_ui = media_router_dialog->GetWebUI();
202 if (web_ui) {
203 MediaRouterUI* media_router_ui =
204 static_cast<MediaRouterUI*>(web_ui->GetController());
205 if (media_router_ui)
206 media_router_ui->Close();
210 WebContents* MediaRouterDialogController::CreateMediaRouterDialog() {
211 DCHECK(!initiator_observer_.get());
212 DCHECK(!dialog_observer_.get());
214 Profile* profile =
215 Profile::FromBrowserContext(initiator_->GetBrowserContext());
216 DCHECK(profile);
218 WebDialogDelegate* web_dialog_delegate = new MediaRouterDialogDelegate;
220 // |web_dialog_delegate|'s owner is |constrained_delegate|.
221 // |constrained_delegate| is owned by the parent |views::View|.
222 // TODO(apacible): Remove after autoresizing is implemented for OSX.
223 #if defined(OS_MACOSX)
224 ConstrainedWebDialogDelegate* constrained_delegate =
225 ShowConstrainedWebDialog(profile, web_dialog_delegate, initiator_);
226 #else
227 // TODO(apacible): Adjust min and max sizes based on new WebUI design.
228 gfx::Size min_size = gfx::Size(330, 1);
229 gfx::Size max_size = gfx::Size(500, 500);
230 // |ShowConstrainedWebDialogWithAutoResize()| will end up creating
231 // ConstrainedWebDialogDelegateViewViews containing a WebContents containing
232 // the MediaRouterUI, using the provided |web_dialog_delegate|. Then, the
233 // view is shown as a modal dialog constrained to the |initiator| WebContents.
234 // The dialog will resize between the |min_size| and |max_size| bounds based
235 // on the currently rendered contents.
236 ConstrainedWebDialogDelegate* constrained_delegate =
237 ShowConstrainedWebDialogWithAutoResize(
238 profile, web_dialog_delegate, initiator_, min_size, max_size);
239 #endif
241 WebContents* media_router_dialog = constrained_delegate->GetWebContents();
243 media_router_dialog_pending_ = true;
245 initiator_observer_.reset(new InitiatorWebContentsObserver(
246 initiator_, this));
247 dialog_observer_.reset(new DialogWebContentsObserver(
248 media_router_dialog, this));
249 return media_router_dialog;
252 void MediaRouterDialogController::RemoveObservers() {
253 DCHECK(thread_checker_.CalledOnValidThread());
254 DCHECK(initiator_observer_.get());
255 DCHECK(dialog_observer_.get());
256 initiator_observer_.reset();
257 dialog_observer_.reset();
260 void MediaRouterDialogController::OnDialogNavigated(
261 const content::LoadCommittedDetails& details) {
262 DCHECK(thread_checker_.CalledOnValidThread());
263 WebContents* media_router_dialog = GetMediaRouterDialog();
264 CHECK(media_router_dialog);
265 ui::PageTransition transition_type = details.entry->GetTransitionType();
266 content::NavigationType nav_type = details.type;
268 // New |media_router_dialog| is created.
269 DCHECK(media_router_dialog_pending_);
270 DCHECK(transition_type == ui::PAGE_TRANSITION_AUTO_TOPLEVEL &&
271 nav_type == content::NAVIGATION_TYPE_NEW_PAGE)
272 << "transition_type: " << transition_type << ", "
273 << "nav_type: " << nav_type;
275 media_router_dialog_pending_ = false;
277 // TODO(imcheng): Initialize dialog.
280 } // namespace media_router