Give names to all utility processes.
[chromium-blink-merge.git] / chrome / browser / extensions / extension_view_host.cc
blob40c48fe316356c14e418b4fa21aaa5d367078d22
1 // Copyright 2013 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/extensions/extension_view_host.h"
7 #include "base/strings/string_piece.h"
8 #include "chrome/browser/chrome_notification_types.h"
9 #include "chrome/browser/extensions/extension_view.h"
10 #include "chrome/browser/extensions/window_controller.h"
11 #include "chrome/browser/file_select_helper.h"
12 #include "chrome/browser/platform_util.h"
13 #include "chrome/browser/ui/browser.h"
14 #include "chrome/browser/ui/browser_dialogs.h"
15 #include "components/web_modal/web_contents_modal_dialog_manager.h"
16 #include "content/public/browser/notification_source.h"
17 #include "content/public/browser/render_view_host.h"
18 #include "content/public/browser/web_contents.h"
19 #include "extensions/browser/extension_system.h"
20 #include "extensions/browser/runtime_data.h"
21 #include "extensions/common/extension_messages.h"
22 #include "grit/browser_resources.h"
23 #include "third_party/WebKit/public/web/WebInputEvent.h"
24 #include "ui/base/resource/resource_bundle.h"
25 #include "ui/events/keycodes/keyboard_codes.h"
27 using content::NativeWebKeyboardEvent;
28 using content::OpenURLParams;
29 using content::RenderViewHost;
30 using content::WebContents;
31 using content::WebContentsObserver;
32 using web_modal::WebContentsModalDialogManager;
34 namespace extensions {
36 // Notifies an ExtensionViewHost when a WebContents is destroyed.
37 class ExtensionViewHost::AssociatedWebContentsObserver
38 : public WebContentsObserver {
39 public:
40 AssociatedWebContentsObserver(ExtensionViewHost* host,
41 WebContents* web_contents)
42 : WebContentsObserver(web_contents), host_(host) {}
43 ~AssociatedWebContentsObserver() override {}
45 // content::WebContentsObserver:
46 void WebContentsDestroyed() override {
47 // Deleting |this| from here is safe.
48 host_->SetAssociatedWebContents(NULL);
51 private:
52 ExtensionViewHost* host_;
54 DISALLOW_COPY_AND_ASSIGN(AssociatedWebContentsObserver);
57 ExtensionViewHost::ExtensionViewHost(
58 const Extension* extension,
59 content::SiteInstance* site_instance,
60 const GURL& url,
61 ViewType host_type)
62 : ExtensionHost(extension, site_instance, url, host_type),
63 associated_web_contents_(NULL) {
64 // Not used for panels, see PanelHost.
65 DCHECK(host_type == VIEW_TYPE_EXTENSION_DIALOG ||
66 host_type == VIEW_TYPE_EXTENSION_POPUP);
69 ExtensionViewHost::~ExtensionViewHost() {
70 // The hosting WebContents will be deleted in the base class, so unregister
71 // this object before it deletes the attached WebContentsModalDialogManager.
72 WebContentsModalDialogManager* manager =
73 WebContentsModalDialogManager::FromWebContents(host_contents());
74 if (manager)
75 manager->SetDelegate(NULL);
78 void ExtensionViewHost::CreateView(Browser* browser) {
79 view_ = CreateExtensionView(this, browser);
82 void ExtensionViewHost::SetAssociatedWebContents(WebContents* web_contents) {
83 associated_web_contents_ = web_contents;
84 if (associated_web_contents_) {
85 // Observe the new WebContents for deletion.
86 associated_web_contents_observer_.reset(
87 new AssociatedWebContentsObserver(this, associated_web_contents_));
88 } else {
89 associated_web_contents_observer_.reset();
93 void ExtensionViewHost::UnhandledKeyboardEvent(
94 WebContents* source,
95 const content::NativeWebKeyboardEvent& event) {
96 view_->HandleKeyboardEvent(source, event);
99 // ExtensionHost overrides:
101 void ExtensionViewHost::OnDidStopFirstLoad() {
102 view_->DidStopLoading();
105 void ExtensionViewHost::LoadInitialURL() {
106 if (!ExtensionSystem::Get(browser_context())->
107 runtime_data()->IsBackgroundPageReady(extension())) {
108 // Make sure the background page loads before any others.
109 registrar_.Add(this,
110 extensions::NOTIFICATION_EXTENSION_BACKGROUND_PAGE_READY,
111 content::Source<Extension>(extension()));
112 return;
115 // Popups may spawn modal dialogs, which need positioning information.
116 if (extension_host_type() == VIEW_TYPE_EXTENSION_POPUP) {
117 WebContentsModalDialogManager::CreateForWebContents(host_contents());
118 WebContentsModalDialogManager::FromWebContents(
119 host_contents())->SetDelegate(this);
120 if (!popup_manager_.get())
121 popup_manager_.reset(new web_modal::PopupManager(this));
122 popup_manager_->RegisterWith(host_contents());
125 ExtensionHost::LoadInitialURL();
128 bool ExtensionViewHost::IsBackgroundPage() const {
129 DCHECK(view_);
130 return false;
133 // content::WebContentsDelegate overrides:
135 WebContents* ExtensionViewHost::OpenURLFromTab(
136 WebContents* source,
137 const OpenURLParams& params) {
138 // Whitelist the dispositions we will allow to be opened.
139 switch (params.disposition) {
140 case SINGLETON_TAB:
141 case NEW_FOREGROUND_TAB:
142 case NEW_BACKGROUND_TAB:
143 case NEW_POPUP:
144 case NEW_WINDOW:
145 case SAVE_TO_DISK:
146 case OFF_THE_RECORD: {
147 // Only allow these from hosts that are bound to a browser (e.g. popups).
148 // Otherwise they are not driven by a user gesture.
149 Browser* browser = view_->GetBrowser();
150 return browser ? browser->OpenURL(params) : NULL;
152 default:
153 return NULL;
157 bool ExtensionViewHost::PreHandleKeyboardEvent(
158 WebContents* source,
159 const NativeWebKeyboardEvent& event,
160 bool* is_keyboard_shortcut) {
161 if (extension_host_type() == VIEW_TYPE_EXTENSION_POPUP &&
162 event.type == NativeWebKeyboardEvent::RawKeyDown &&
163 event.windowsKeyCode == ui::VKEY_ESCAPE) {
164 DCHECK(is_keyboard_shortcut != NULL);
165 *is_keyboard_shortcut = true;
166 return false;
169 // Handle higher priority browser shortcuts such as Ctrl-w.
170 Browser* browser = view_->GetBrowser();
171 if (browser)
172 return browser->PreHandleKeyboardEvent(source, event, is_keyboard_shortcut);
174 *is_keyboard_shortcut = false;
175 return false;
178 void ExtensionViewHost::HandleKeyboardEvent(
179 WebContents* source,
180 const NativeWebKeyboardEvent& event) {
181 if (extension_host_type() == VIEW_TYPE_EXTENSION_POPUP) {
182 if (event.type == NativeWebKeyboardEvent::RawKeyDown &&
183 event.windowsKeyCode == ui::VKEY_ESCAPE) {
184 Close();
185 return;
188 UnhandledKeyboardEvent(source, event);
191 bool ExtensionViewHost::PreHandleGestureEvent(
192 content::WebContents* source,
193 const blink::WebGestureEvent& event) {
194 // Disable pinch zooming.
195 return event.type == blink::WebGestureEvent::GesturePinchBegin ||
196 event.type == blink::WebGestureEvent::GesturePinchUpdate ||
197 event.type == blink::WebGestureEvent::GesturePinchEnd;
200 content::ColorChooser* ExtensionViewHost::OpenColorChooser(
201 WebContents* web_contents,
202 SkColor initial_color,
203 const std::vector<content::ColorSuggestion>& suggestions) {
204 // Similar to the file chooser below, opening a color chooser requires a
205 // visible <input> element to click on. Therefore this code only exists for
206 // extensions with a view.
207 return chrome::ShowColorChooser(web_contents, initial_color);
210 void ExtensionViewHost::RunFileChooser(
211 WebContents* tab,
212 const content::FileChooserParams& params) {
213 // For security reasons opening a file picker requires a visible <input>
214 // element to click on, so this code only exists for extensions with a view.
215 FileSelectHelper::RunFileChooser(tab, params);
219 void ExtensionViewHost::ResizeDueToAutoResize(WebContents* source,
220 const gfx::Size& new_size) {
221 view_->ResizeDueToAutoResize(new_size);
224 // content::WebContentsObserver overrides:
226 void ExtensionViewHost::RenderViewCreated(RenderViewHost* render_view_host) {
227 ExtensionHost::RenderViewCreated(render_view_host);
229 view_->RenderViewCreated();
231 // If the host is bound to a window, then extract its id. Extensions hosted
232 // in ExternalTabContainer objects may not have an associated window.
233 WindowController* window = GetExtensionWindowController();
234 if (window) {
235 render_view_host->Send(new ExtensionMsg_UpdateBrowserWindowId(
236 render_view_host->GetRoutingID(), window->GetWindowId()));
240 // web_modal::WebContentsModalDialogManagerDelegate overrides:
242 web_modal::WebContentsModalDialogHost*
243 ExtensionViewHost::GetWebContentsModalDialogHost() {
244 return this;
247 bool ExtensionViewHost::IsWebContentsVisible(WebContents* web_contents) {
248 return platform_util::IsVisible(web_contents->GetNativeView());
251 gfx::NativeView ExtensionViewHost::GetHostView() const {
252 return view_->GetNativeView();
255 gfx::Point ExtensionViewHost::GetDialogPosition(const gfx::Size& size) {
256 if (!GetVisibleWebContents())
257 return gfx::Point();
258 gfx::Rect bounds = GetVisibleWebContents()->GetViewBounds();
259 return gfx::Point(
260 std::max(0, (bounds.width() - size.width()) / 2),
261 std::max(0, (bounds.height() - size.height()) / 2));
264 gfx::Size ExtensionViewHost::GetMaximumDialogSize() {
265 if (!GetVisibleWebContents())
266 return gfx::Size();
267 return GetVisibleWebContents()->GetViewBounds().size();
270 void ExtensionViewHost::AddObserver(
271 web_modal::ModalDialogHostObserver* observer) {
274 void ExtensionViewHost::RemoveObserver(
275 web_modal::ModalDialogHostObserver* observer) {
278 WindowController* ExtensionViewHost::GetExtensionWindowController() const {
279 Browser* browser = view_->GetBrowser();
280 return browser ? browser->extension_window_controller() : NULL;
283 WebContents* ExtensionViewHost::GetAssociatedWebContents() const {
284 return associated_web_contents_;
287 WebContents* ExtensionViewHost::GetVisibleWebContents() const {
288 if (associated_web_contents_)
289 return associated_web_contents_;
290 if (extension_host_type() == VIEW_TYPE_EXTENSION_POPUP)
291 return host_contents();
292 return NULL;
295 void ExtensionViewHost::Observe(int type,
296 const content::NotificationSource& source,
297 const content::NotificationDetails& details) {
298 DCHECK_EQ(type, extensions::NOTIFICATION_EXTENSION_BACKGROUND_PAGE_READY);
299 DCHECK(ExtensionSystem::Get(browser_context())
300 ->runtime_data()
301 ->IsBackgroundPageReady(extension()));
302 LoadInitialURL();
305 } // namespace extensions