[Metrics] Make MetricsStateManager take a callback param to check if UMA is enabled.
[chromium-blink-merge.git] / chrome / browser / ui / views / extensions / extension_dialog.cc
blobba2c1c774a0a0a86dd1c0aad1192e9bab1941c9c
1 // Copyright (c) 2012 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/views/extensions/extension_dialog.h"
7 #include "chrome/browser/chrome_notification_types.h"
8 #include "chrome/browser/extensions/extension_view_host.h"
9 #include "chrome/browser/extensions/extension_view_host_factory.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/ui/views/constrained_window_views.h"
12 #include "chrome/browser/ui/views/extensions/extension_dialog_observer.h"
13 #include "content/public/browser/notification_details.h"
14 #include "content/public/browser/notification_source.h"
15 #include "content/public/browser/render_view_host.h"
16 #include "content/public/browser/render_widget_host_view.h"
17 #include "content/public/browser/web_contents.h"
18 #include "ui/base/base_window.h"
19 #include "ui/gfx/screen.h"
20 #include "ui/views/background.h"
21 #include "ui/views/widget/widget.h"
22 #include "url/gurl.h"
24 using content::BrowserContext;
25 using content::WebContents;
27 ExtensionDialog::ExtensionDialog(extensions::ExtensionViewHost* host,
28 ExtensionDialogObserver* observer)
29 : host_(host),
30 observer_(observer) {
31 AddRef(); // Balanced in DeleteDelegate();
33 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING,
34 content::Source<BrowserContext>(host->browser_context()));
35 // Listen for the containing view calling window.close();
36 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE,
37 content::Source<BrowserContext>(host->browser_context()));
38 // Listen for a crash or other termination of the extension process.
39 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED,
40 content::Source<BrowserContext>(host->browser_context()));
43 ExtensionDialog::~ExtensionDialog() {
46 // static
47 ExtensionDialog* ExtensionDialog::Show(
48 const GURL& url,
49 aura::Window* parent_window,
50 Profile* profile,
51 WebContents* web_contents,
52 int width,
53 int height,
54 int min_width,
55 int min_height,
56 const base::string16& title,
57 ExtensionDialogObserver* observer) {
58 extensions::ExtensionViewHost* host =
59 extensions::ExtensionViewHostFactory::CreateDialogHost(url, profile);
60 if (!host)
61 return NULL;
62 // Preferred size must be set before views::Widget::CreateWindowWithParent
63 // is called because CreateWindowWithParent refers the result of CanResize().
64 host->view()->SetPreferredSize(gfx::Size(width, height));
65 host->view()->set_minimum_size(gfx::Size(min_width, min_height));
66 host->SetAssociatedWebContents(web_contents);
68 DCHECK(parent_window);
69 ExtensionDialog* dialog = new ExtensionDialog(host, observer);
70 dialog->set_title(title);
71 dialog->InitWindow(parent_window, width, height);
73 // Show a white background while the extension loads. This is prettier than
74 // flashing a black unfilled window frame.
75 host->view()->set_background(
76 views::Background::CreateSolidBackground(0xFF, 0xFF, 0xFF));
77 host->view()->SetVisible(true);
79 // Ensure the DOM JavaScript can respond immediately to keyboard shortcuts.
80 host->host_contents()->Focus();
81 return dialog;
84 void ExtensionDialog::InitWindow(aura::Window* parent,
85 int width,
86 int height) {
87 views::Widget* window = CreateBrowserModalDialogViews(this, parent);
89 // Center the window over the browser.
90 gfx::Point center = parent->GetBoundsInScreen().CenterPoint();
91 int x = center.x() - width / 2;
92 int y = center.y() - height / 2;
93 // Ensure the top left and top right of the window are on screen, with
94 // priority given to the top left.
95 gfx::Rect screen_rect = gfx::Screen::GetScreenFor(parent)->
96 GetDisplayNearestPoint(center).bounds();
97 gfx::Rect bounds_rect = gfx::Rect(x, y, width, height);
98 bounds_rect.AdjustToFit(screen_rect);
99 window->SetBounds(bounds_rect);
101 window->Show();
102 // TODO(jamescook): Remove redundant call to Activate()?
103 window->Activate();
106 void ExtensionDialog::ObserverDestroyed() {
107 observer_ = NULL;
110 void ExtensionDialog::MaybeFocusRenderView() {
111 views::FocusManager* focus_manager = GetWidget()->GetFocusManager();
112 DCHECK(focus_manager != NULL);
114 // Already there's a focused view, so no need to switch the focus.
115 if (focus_manager->GetFocusedView())
116 return;
118 content::RenderWidgetHostView* view = host()->render_view_host()->GetView();
119 if (!view)
120 return;
122 view->Focus();
125 /////////////////////////////////////////////////////////////////////////////
126 // views::DialogDelegate overrides.
128 int ExtensionDialog::GetDialogButtons() const {
129 // The only user, SelectFileDialogExtension, provides its own buttons.
130 return ui::DIALOG_BUTTON_NONE;
133 bool ExtensionDialog::CanResize() const {
134 // Can resize only if minimum contents size set.
135 return host_->view()->GetPreferredSize() != gfx::Size();
138 void ExtensionDialog::SetMinimumContentsSize(int width, int height) {
139 host_->view()->SetPreferredSize(gfx::Size(width, height));
142 ui::ModalType ExtensionDialog::GetModalType() const {
143 return ui::MODAL_TYPE_WINDOW;
146 bool ExtensionDialog::ShouldShowWindowTitle() const {
147 return !window_title_.empty();
150 base::string16 ExtensionDialog::GetWindowTitle() const {
151 return window_title_;
154 void ExtensionDialog::WindowClosing() {
155 if (observer_)
156 observer_->ExtensionDialogClosing(this);
159 void ExtensionDialog::DeleteDelegate() {
160 // The window has finished closing. Allow ourself to be deleted.
161 Release();
164 views::Widget* ExtensionDialog::GetWidget() {
165 return host_->view()->GetWidget();
168 const views::Widget* ExtensionDialog::GetWidget() const {
169 return host_->view()->GetWidget();
172 views::View* ExtensionDialog::GetContentsView() {
173 return host_->view();
176 bool ExtensionDialog::UseNewStyleForThisDialog() const {
177 return false;
180 /////////////////////////////////////////////////////////////////////////////
181 // content::NotificationObserver overrides.
183 void ExtensionDialog::Observe(int type,
184 const content::NotificationSource& source,
185 const content::NotificationDetails& details) {
186 switch (type) {
187 case chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING:
188 // Avoid potential overdraw by removing the temporary background after
189 // the extension finishes loading.
190 host_->view()->set_background(NULL);
191 // The render view is created during the LoadURL(), so we should
192 // set the focus to the view if nobody else takes the focus.
193 if (content::Details<extensions::ExtensionHost>(host()) == details)
194 MaybeFocusRenderView();
195 break;
196 case chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE:
197 // If we aren't the host of the popup, then disregard the notification.
198 if (content::Details<extensions::ExtensionHost>(host()) != details)
199 return;
200 GetWidget()->Close();
201 break;
202 case chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED:
203 if (content::Details<extensions::ExtensionHost>(host()) != details)
204 return;
205 if (observer_)
206 observer_->ExtensionTerminated(this);
207 break;
208 default:
209 NOTREACHED() << L"Received unexpected notification";
210 break;