1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file.
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/extensions/extension_view_host.h"
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/strings/string_piece.h"
8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/chrome_notification_types.h"
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/extensions/extension_view.h"
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/extensions/window_controller.h"
11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/file_select_helper.h"
12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/platform_util.h"
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/browser.h"
14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/ui/browser_dialogs.h"
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/web_modal/web_contents_modal_dialog_manager.h"
16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/browser/notification_source.h"
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/browser/render_view_host.h"
18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/browser/web_contents.h"
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h"
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/runtime_data.h"
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/common/extension_messages.h"
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "grit/browser_resources.h"
2323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "third_party/WebKit/public/web/WebInputEvent.h"
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/events/keycodes/keyboard_codes.h"
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using content::NativeWebKeyboardEvent;
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using content::OpenURLParams;
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using content::RenderViewHost;
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using content::WebContents;
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using content::WebContentsObserver;
32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)using web_modal::WebContentsModalDialogManager;
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace extensions {
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Notifies an ExtensionViewHost when a WebContents is destroyed.
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class ExtensionViewHost::AssociatedWebContentsObserver
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    : public WebContentsObserver {
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AssociatedWebContentsObserver(ExtensionViewHost* host,
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                WebContents* web_contents)
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      : WebContentsObserver(web_contents), host_(host) {}
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~AssociatedWebContentsObserver() {}
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // content::WebContentsObserver:
46010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  virtual void WebContentsDestroyed() OVERRIDE {
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Deleting |this| from here is safe.
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    host_->SetAssociatedWebContents(NULL);
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private:
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ExtensionViewHost* host_;
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AssociatedWebContentsObserver);
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ExtensionViewHost::ExtensionViewHost(
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const Extension* extension,
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    content::SiteInstance* site_instance,
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const GURL& url,
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ViewType host_type)
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    : ExtensionHost(extension, site_instance, url, host_type),
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      associated_web_contents_(NULL) {
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Not used for panels, see PanelHost.
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(host_type == VIEW_TYPE_EXTENSION_DIALOG ||
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)         host_type == VIEW_TYPE_EXTENSION_INFOBAR ||
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)         host_type == VIEW_TYPE_EXTENSION_POPUP);
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)ExtensionViewHost::~ExtensionViewHost() {
71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // The hosting WebContents will be deleted in the base class, so unregister
72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // this object before it deletes the attached WebContentsModalDialogManager.
73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  WebContentsModalDialogManager* manager =
74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      WebContentsModalDialogManager::FromWebContents(host_contents());
75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (manager)
76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    manager->SetDelegate(NULL);
77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ExtensionViewHost::CreateView(Browser* browser) {
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  view_ = CreateExtensionView(this, browser);
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  view_->Init();
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ExtensionViewHost::SetAssociatedWebContents(WebContents* web_contents) {
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  associated_web_contents_ = web_contents;
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (associated_web_contents_) {
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Observe the new WebContents for deletion.
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    associated_web_contents_observer_.reset(
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new AssociatedWebContentsObserver(this, associated_web_contents_));
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else {
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    associated_web_contents_observer_.reset();
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ExtensionViewHost::UnhandledKeyboardEvent(
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    WebContents* source,
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const content::NativeWebKeyboardEvent& event) {
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  view_->HandleKeyboardEvent(source, event);
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// ExtensionHost overrides:
102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ExtensionViewHost::OnDidStopLoading() {
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(did_stop_loading());
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  view_->DidStopLoading();
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ExtensionViewHost::OnDocumentAvailable() {
109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (extension_host_type() == VIEW_TYPE_EXTENSION_INFOBAR) {
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // No style sheet for other types, at the moment.
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    InsertInfobarCSS();
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ExtensionViewHost::LoadInitialURL() {
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!ExtensionSystem::Get(browser_context())->
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          runtime_data()->IsBackgroundPageReady(extension())) {
118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Make sure the background page loads before any others.
119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    registrar()->Add(this,
1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                     extensions::NOTIFICATION_EXTENSION_BACKGROUND_PAGE_READY,
121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     content::Source<Extension>(extension()));
122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Popups may spawn modal dialogs, which need positioning information.
126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (extension_host_type() == VIEW_TYPE_EXTENSION_POPUP) {
127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    WebContentsModalDialogManager::CreateForWebContents(host_contents());
128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    WebContentsModalDialogManager::FromWebContents(
129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        host_contents())->SetDelegate(this);
130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (!popup_manager_.get())
131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      popup_manager_.reset(new web_modal::PopupManager(this));
132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    popup_manager_->RegisterWith(host_contents());
133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ExtensionHost::LoadInitialURL();
136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool ExtensionViewHost::IsBackgroundPage() const {
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(view_);
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return false;
141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// content::WebContentsDelegate overrides:
144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)WebContents* ExtensionViewHost::OpenURLFromTab(
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    WebContents* source,
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const OpenURLParams& params) {
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Whitelist the dispositions we will allow to be opened.
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  switch (params.disposition) {
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case SINGLETON_TAB:
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case NEW_FOREGROUND_TAB:
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case NEW_BACKGROUND_TAB:
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case NEW_POPUP:
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case NEW_WINDOW:
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case SAVE_TO_DISK:
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case OFF_THE_RECORD: {
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // Only allow these from hosts that are bound to a browser (e.g. popups).
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // Otherwise they are not driven by a user gesture.
159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      Browser* browser = view_->GetBrowser();
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return browser ? browser->OpenURL(params) : NULL;
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    default:
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return NULL;
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool ExtensionViewHost::PreHandleKeyboardEvent(
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    WebContents* source,
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const NativeWebKeyboardEvent& event,
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool* is_keyboard_shortcut) {
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (extension_host_type() == VIEW_TYPE_EXTENSION_POPUP &&
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      event.type == NativeWebKeyboardEvent::RawKeyDown &&
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      event.windowsKeyCode == ui::VKEY_ESCAPE) {
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK(is_keyboard_shortcut != NULL);
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    *is_keyboard_shortcut = true;
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return false;
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Handle higher priority browser shortcuts such as Ctrl-w.
180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  Browser* browser = view_->GetBrowser();
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (browser)
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return browser->PreHandleKeyboardEvent(source, event, is_keyboard_shortcut);
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  *is_keyboard_shortcut = false;
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return false;
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ExtensionViewHost::HandleKeyboardEvent(
189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    WebContents* source,
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const NativeWebKeyboardEvent& event) {
191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (extension_host_type() == VIEW_TYPE_EXTENSION_POPUP) {
192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (event.type == NativeWebKeyboardEvent::RawKeyDown &&
193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        event.windowsKeyCode == ui::VKEY_ESCAPE) {
194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      Close();
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return;
196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  UnhandledKeyboardEvent(source, event);
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
20123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)bool ExtensionViewHost::PreHandleGestureEvent(
20223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    content::WebContents* source,
20323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const blink::WebGestureEvent& event) {
20423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Disable pinch zooming.
20523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return event.type == blink::WebGestureEvent::GesturePinchBegin ||
20623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      event.type == blink::WebGestureEvent::GesturePinchUpdate ||
20723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      event.type == blink::WebGestureEvent::GesturePinchEnd;
20823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
20923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
210a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)content::ColorChooser* ExtensionViewHost::OpenColorChooser(
211a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    WebContents* web_contents,
212a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SkColor initial_color,
213a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const std::vector<content::ColorSuggestion>& suggestions) {
214a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Similar to the file chooser below, opening a color chooser requires a
215a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // visible <input> element to click on. Therefore this code only exists for
216a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // extensions with a view.
217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return chrome::ShowColorChooser(web_contents, initial_color);
218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
219a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ExtensionViewHost::RunFileChooser(
221a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    WebContents* tab,
222a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const content::FileChooserParams& params) {
223a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // For security reasons opening a file picker requires a visible <input>
224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // element to click on, so this code only exists for extensions with a view.
225a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  FileSelectHelper::RunFileChooser(tab, params);
226a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
228a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ExtensionViewHost::ResizeDueToAutoResize(WebContents* source,
230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                          const gfx::Size& new_size) {
231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  view_->ResizeDueToAutoResize(new_size);
232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// content::WebContentsObserver overrides:
235f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ExtensionViewHost::RenderViewCreated(RenderViewHost* render_view_host) {
237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ExtensionHost::RenderViewCreated(render_view_host);
238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  view_->RenderViewCreated();
240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // If the host is bound to a window, then extract its id. Extensions hosted
242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // in ExternalTabContainer objects may not have an associated window.
243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  WindowController* window = GetExtensionWindowController();
244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (window) {
245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    render_view_host->Send(new ExtensionMsg_UpdateBrowserWindowId(
246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        render_view_host->GetRoutingID(), window->GetWindowId()));
247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
250a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// web_modal::WebContentsModalDialogManagerDelegate overrides:
251a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)web_modal::WebContentsModalDialogHost*
253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)ExtensionViewHost::GetWebContentsModalDialogHost() {
254a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return this;
255a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
257a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool ExtensionViewHost::IsWebContentsVisible(WebContents* web_contents) {
258010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return platform_util::IsVisible(web_contents->GetNativeView());
259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
260a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)gfx::NativeView ExtensionViewHost::GetHostView() const {
262116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return view_->GetNativeView();
263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
264a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
265a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)gfx::Point ExtensionViewHost::GetDialogPosition(const gfx::Size& size) {
266a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!GetVisibleWebContents())
267a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return gfx::Point();
268010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  gfx::Rect bounds = GetVisibleWebContents()->GetViewBounds();
269a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return gfx::Point(
270a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      std::max(0, (bounds.width() - size.width()) / 2),
271a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      std::max(0, (bounds.height() - size.height()) / 2));
272a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
273a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
274a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)gfx::Size ExtensionViewHost::GetMaximumDialogSize() {
275a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!GetVisibleWebContents())
276a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return gfx::Size();
277010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return GetVisibleWebContents()->GetViewBounds().size();
278a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
279a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
280a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ExtensionViewHost::AddObserver(
281a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    web_modal::ModalDialogHostObserver* observer) {
282a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
283a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
284a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ExtensionViewHost::RemoveObserver(
285a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    web_modal::ModalDialogHostObserver* observer) {
286a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)WindowController* ExtensionViewHost::GetExtensionWindowController() const {
289116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  Browser* browser = view_->GetBrowser();
290116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return browser ? browser->extension_window_controller() : NULL;
291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)WebContents* ExtensionViewHost::GetAssociatedWebContents() const {
294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return associated_web_contents_;
295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)WebContents* ExtensionViewHost::GetVisibleWebContents() const {
298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (associated_web_contents_)
299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return associated_web_contents_;
300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (extension_host_type() == VIEW_TYPE_EXTENSION_POPUP)
301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return host_contents();
302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return NULL;
303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ExtensionViewHost::Observe(int type,
306a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                const content::NotificationSource& source,
307a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                const content::NotificationDetails& details) {
3085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (type == extensions::NOTIFICATION_EXTENSION_BACKGROUND_PAGE_READY) {
3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(ExtensionSystem::Get(browser_context())->
3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)               runtime_data()->IsBackgroundPageReady(extension()));
311a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    LoadInitialURL();
312a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
313a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
314a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ExtensionHost::Observe(type, source, details);
315a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
316a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ExtensionViewHost::InsertInfobarCSS() {
318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static const base::StringPiece css(
319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      ResourceBundle::GetSharedInstance().GetRawDataResource(
320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      IDR_EXTENSIONS_INFOBAR_CSS));
321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
322c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  host_contents()->InsertCSS(css.as_string());
323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace extensions
326