172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_host.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <list> 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/singleton.h" 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h" 11731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/metrics/histogram.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser_shutdown.h" 1421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/extensions/extension_service.h" 15dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/extensions/extension_tabs_module.h" 163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/file_select_helper.h" 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/platform_util.h" 1821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h" 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/renderer_preferences_util.h" 20513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/browser/tab_contents/popup_menu_helper_mac.h" 2121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/app_modal_dialogs/message_box_handler.h" 224a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/ui/browser.h" 23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_list.h" 24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_window.h" 25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/webui/chrome_web_ui_factory.h" 26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/common/chrome_constants.h" 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/extension.h" 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/extension_constants.h" 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/render_messages.h" 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/url_constants.h" 313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/view_types.h" 32dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browsing_instance.h" 33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/browser/renderer_host/browser_render_process_host.h" 34dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_process_host.h" 35dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_view_host.h" 36dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_widget_host.h" 37dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_widget_host_view.h" 38dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/site_instance.h" 39dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h" 40dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents_view.h" 41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/bindings_policy.h" 42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/native_web_keyboard_event.h" 43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h" 44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/view_messages.h" 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/browser_resources.h" 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h" 4772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/keycodes/keyboard_codes.h" 4872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h" 4972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/resource/resource_bundle.h" 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/context_menu.h" 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(TOOLKIT_VIEWS) 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/widget/widget.h" 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebDragOperation; 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebDragOperationsMask; 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ExtensionHost::enable_dom_automation_ = false; 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Helper class that rate-limits the creation of renderer processes for 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ExtensionHosts, to avoid blocking the UI. 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ExtensionHost::ProcessCreationQueue { 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 6621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen static ProcessCreationQueue* GetInstance() { 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return Singleton<ProcessCreationQueue>::get(); 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Add a host to the queue for RenderView creation. 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void CreateSoon(ExtensionHost* host) { 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch queue_.push_back(host); 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PostTask(); 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Remove a host from the queue (in case it's being deleted). 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void Remove(ExtensionHost* host) { 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Queue::iterator it = std::find(queue_.begin(), queue_.end(), host); 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (it != queue_.end()) 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch queue_.erase(it); 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch friend class Singleton<ProcessCreationQueue>; 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch friend struct DefaultSingletonTraits<ProcessCreationQueue>; 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ProcessCreationQueue() 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : pending_create_(false), 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { } 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Queue up a delayed task to process the next ExtensionHost in the queue. 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void PostTask() { 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!pending_create_) { 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->PostTask(FROM_HERE, 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch method_factory_.NewRunnableMethod( 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &ProcessCreationQueue::ProcessOneHost)); 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch pending_create_ = true; 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Create the RenderView for the next host in the queue. 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void ProcessOneHost() { 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch pending_create_ = false; 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (queue_.empty()) 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; // can happen on shutdown 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch queue_.front()->CreateRenderViewNow(); 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch queue_.pop_front(); 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!queue_.empty()) 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PostTask(); 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch typedef std::list<ExtensionHost*> Queue; 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Queue queue_; 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool pending_create_; 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ScopedRunnableMethodFactory<ProcessCreationQueue> method_factory_; 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//////////////// 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ExtensionHost 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 122513209b27ff55e2841eac0e4120199c23acce758Ben MurdochExtensionHost::ExtensionHost(const Extension* extension, 123513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SiteInstance* site_instance, 124513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const GURL& url, 125513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ViewType::Type host_type) 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : extension_(extension), 127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen extension_id_(extension->id()), 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_(site_instance->browsing_instance()->profile()), 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch did_stop_loading_(false), 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch document_element_available_(false), 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url_(url), 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch extension_host_type_(host_type), 133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen associated_tab_contents_(NULL), 134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen suppress_javascript_messages_(false) { 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_view_host_ = new RenderViewHost(site_instance, this, MSG_ROUTING_NONE, 1363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NULL); 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_view_host_->set_is_extension_process(true); 138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (extension->is_app()) { 139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserRenderProcessHost* process = static_cast<BrowserRenderProcessHost*>( 140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen render_view_host_->process()); 141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen process->set_installed_app(extension); 142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_view_host_->AllowBindings(BindingsPolicy::EXTENSION); 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (enable_dom_automation_) 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_view_host_->AllowBindings(BindingsPolicy::DOM_AUTOMATION); 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Listen for when the render process' handle is available so we can add it 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // to the task manager then. 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch registrar_.Add(this, NotificationType::RENDERER_PROCESS_CREATED, 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Source<RenderProcessHost>(render_process_host())); 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Listen for when an extension is unloaded from the same profile, as it may 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // be the same extension that this points to. 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch registrar_.Add(this, NotificationType::EXTENSION_UNLOADED, 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Source<Profile>(profile_)); 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionHost::~ExtensionHost() { 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::current()->Notify( 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationType::EXTENSION_HOST_DESTROYED, 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Source<Profile>(profile_), 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Details<ExtensionHost>(this)); 16221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ProcessCreationQueue::GetInstance()->Remove(this); 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_view_host_->Shutdown(); // deletes render_view_host 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHost::CreateView(Browser* browser) { 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(TOOLKIT_VIEWS) 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch view_.reset(new ExtensionView(this, browser)); 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We own |view_|, so don't auto delete when it's removed from the view 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // hierarchy. 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch view_->set_parent_owned(false); 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_MACOSX) 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch view_.reset(new ExtensionViewMac(this, browser)); 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch view_->Init(); 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(TOOLKIT_USES_GTK) 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch view_.reset(new ExtensionViewGtk(this, browser)); 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch view_->Init(); 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(port) 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 18421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTabContents* ExtensionHost::associated_tab_contents() const { 18521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return associated_tab_contents_; 18621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 18721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochRenderProcessHost* ExtensionHost::render_process_host() const { 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return render_view_host_->process(); 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSiteInstance* ExtensionHost::site_instance() const { 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return render_view_host_->site_instance(); 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ExtensionHost::IsRenderViewLive() const { 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return render_view_host_->IsRenderViewLive(); 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHost::CreateRenderViewSoon(RenderWidgetHostView* host_view) { 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_view_host_->set_view(host_view); 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (render_view_host_->process()->HasConnection()) { 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If the process is already started, go ahead and initialize the RenderView 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // synchronously. The process creation is the real meaty part that we want 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // to defer. 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateRenderViewNow(); 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 20821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ProcessCreationQueue::GetInstance()->CreateSoon(this); 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHost::CreateRenderViewNow() { 2133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick render_view_host_->CreateRenderView(string16()); 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NavigateToURL(url_); 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(IsRenderViewLive()); 2163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (is_background_page()) 21721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen profile_->GetExtensionService()->DidCreateRenderViewForBackgroundPage( 2183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick this); 2193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 22172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenconst Browser* ExtensionHost::GetBrowser() const { 22272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return view() ? view()->browser() : NULL; 22372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 22472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 22572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenBrowser* ExtensionHost::GetBrowser() { 2263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return view() ? view()->browser() : NULL; 2273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickgfx::NativeView ExtensionHost::GetNativeViewOfHost() { 2303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return view() ? view()->native_view() : NULL; 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHost::NavigateToURL(const GURL& url) { 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Prevent explicit navigation to another extension id's pages. 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This method is only called by some APIs, so we still need to protect 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // DidNavigate below (location = ""). 237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (url.SchemeIs(chrome::kExtensionScheme) && url.host() != extension_id()) { 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(erikkay) communicate this back to the caller? 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url_ = url; 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 244513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!is_background_page() && 24521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen !profile_->GetExtensionService()->IsBackgroundPageReady(extension_)) { 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make sure the background page loads before any others. 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch registrar_.Add(this, NotificationType::EXTENSION_BACKGROUND_PAGE_READY, 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Source<Extension>(extension_)); 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_view_host_->NavigateToURL(url_); 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHost::Observe(NotificationType type, 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const NotificationSource& source, 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const NotificationDetails& details) { 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (type.value) { 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case NotificationType::EXTENSION_BACKGROUND_PAGE_READY: 26021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(profile_->GetExtensionService()-> 261ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen IsBackgroundPageReady(extension_)); 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NavigateToURL(url_); 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case NotificationType::RENDERER_PROCESS_CREATED: 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::current()->Notify( 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationType::EXTENSION_PROCESS_CREATED, 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Source<Profile>(profile_), 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Details<ExtensionHost>(this)); 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case NotificationType::EXTENSION_UNLOADED: 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The extension object will be deleted after this notification has been 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // sent. NULL it out so that dirty pointer issues don't arise in cases 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // when multiple ExtensionHost objects pointing to the same Extension are 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // present. 27521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (extension_ == Details<UnloadedExtensionInfo>(details)->extension) 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch extension_ = NULL; 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default: 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED() << "Unexpected notification sent."; 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHost::UpdatePreferredSize(const gfx::Size& new_size) { 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (view_.get()) 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch view_->UpdatePreferredSize(new_size); 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 289731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid ExtensionHost::UpdateInspectorSetting(const std::string& key, 290731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const std::string& value) { 291731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick RenderViewHostDelegateHelper::UpdateInspectorSetting(profile(), key, value); 292731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 293731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 294731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid ExtensionHost::ClearInspectorSettings() { 295731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick RenderViewHostDelegateHelper::ClearInspectorSettings(profile()); 296731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 297731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 29821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid ExtensionHost::RenderViewGone(RenderViewHost* render_view_host, 29921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen base::TerminationStatus status, 30021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int error_code) { 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // During browser shutdown, we may use sudden termination on an extension 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // process, so it is expected to lose our connection to the render view. 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Do nothing. 304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (browser_shutdown::GetShutdownType() != browser_shutdown::NOT_VALID) 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // In certain cases, multiple ExtensionHost objects may have pointed to 308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the same Extension at some point (one with a background page and a 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // popup, for example). When the first ExtensionHost goes away, the extension 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // is unloaded, and any other host that pointed to that extension will have 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // its pointer to it NULLed out so that any attempt to unload a dirty pointer 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // will be averted. 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!extension_) 314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(render_view_host_, render_view_host); 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::current()->Notify( 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationType::EXTENSION_PROCESS_TERMINATED, 319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Source<Profile>(profile_), 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Details<ExtensionHost>(this)); 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHost::DidNavigate(RenderViewHost* render_view_host, 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const ViewHostMsg_FrameNavigate_Params& params) { 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We only care when the outer frame changes. 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!PageTransition::IsMainFrame(params.transition)) 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!params.url.SchemeIs(chrome::kExtensionScheme)) { 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch extension_function_dispatcher_.reset(NULL); 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url_ = params.url; 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This catches two bogus use cases: 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // (1) URLs that look like chrome-extension://somethingbogus or 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // chrome-extension://nosuchid/, in other words, no Extension would 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // be found. 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // (2) URLs that refer to a different extension than this one. 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // In both cases, we preserve the old URL and reset the EFD to NULL. This 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // will leave the host in kind of a bad state with poor UI and errors, but 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // it's better than the alternative. 3433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // TODO(erikkay) Perhaps we should display errors in developer mode. 344ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (params.url.host() != extension_id()) { 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch extension_function_dispatcher_.reset(NULL); 346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url_ = params.url; 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch extension_function_dispatcher_.reset( 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ExtensionFunctionDispatcher::Create(render_view_host_, this, url_)); 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHost::InsertInfobarCSS() { 355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!is_background_page()); 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const base::StringPiece css( 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ResourceBundle::GetSharedInstance().GetRawDataResource( 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_EXTENSIONS_INFOBAR_CSS)); 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_view_host()->InsertCSSInWebFrame( 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch L"", css.as_string(), "InfobarThemeCSS"); 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHost::DisableScrollbarsForSmallWindows( 366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const gfx::Size& size_limit) { 367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_view_host()->Send(new ViewMsg_DisableScrollbarsForSmallWindows( 368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_view_host()->routing_id(), size_limit)); 369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHost::DidStopLoading() { 372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool notify = !did_stop_loading_; 373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch did_stop_loading_ = true; 3743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (extension_host_type_ == ViewType::EXTENSION_POPUP || 375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch extension_host_type_ == ViewType::EXTENSION_INFOBAR) { 376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(TOOLKIT_VIEWS) 377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (view_.get()) 378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch view_->DidStopLoading(); 379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (notify) { 382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::current()->Notify( 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationType::EXTENSION_HOST_DID_STOP_LOADING, 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Source<Profile>(profile_), 385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Details<ExtensionHost>(this)); 386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (extension_host_type_ == ViewType::EXTENSION_BACKGROUND_PAGE) { 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UMA_HISTOGRAM_TIMES("Extensions.BackgroundPageLoadTime", 388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch since_created_.Elapsed()); 389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (extension_host_type_ == ViewType::EXTENSION_POPUP) { 390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UMA_HISTOGRAM_TIMES("Extensions.PopupLoadTime", 391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch since_created_.Elapsed()); 392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (extension_host_type_ == ViewType::EXTENSION_INFOBAR) { 393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UMA_HISTOGRAM_TIMES("Extensions.InfobarLoadTime", 394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch since_created_.Elapsed()); 395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHost::DocumentAvailableInMainFrame(RenderViewHost* rvh) { 400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If the document has already been marked as available for this host, then 401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // bail. No need for the redundant setup. http://crbug.com/31170 402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (document_element_available_) 403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch document_element_available_ = true; 406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (is_background_page()) { 40721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen profile_->GetExtensionService()->SetBackgroundPageReady(extension_); 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (extension_host_type_) { 410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case ViewType::EXTENSION_INFOBAR: 411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch InsertInfobarCSS(); 412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default: 414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; // No style sheet for other types, at the moment. 415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ExtensionHost::DocumentOnLoadCompletedInMainFrame(RenderViewHost* rvh, 4203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int32 page_id) { 421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (ViewType::EXTENSION_POPUP == GetRenderViewType()) { 422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::current()->Notify( 423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationType::EXTENSION_POPUP_VIEW_READY, 424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Source<Profile>(profile_), 425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Details<ExtensionHost>(this)); 426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHost::RunJavaScriptMessage(const std::wstring& message, 430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::wstring& default_prompt, 431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& frame_url, 432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int flags, 433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IPC::Message* reply_msg, 434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool* did_suppress_message) { 435ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta time_since_last_message( 436ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeTicks::Now() - last_javascript_message_dismissal_); 437ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 438ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *did_suppress_message = suppress_javascript_messages_; 439ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!suppress_javascript_messages_) { 440ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool show_suppress_checkbox = false; 441ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Show a checkbox offering to suppress further messages if this message is 442ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // being displayed within kJavascriptMessageExpectedDelay of the last one. 443ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (time_since_last_message < 444ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::TimeDelta::FromMilliseconds( 445ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen chrome::kJavascriptMessageExpectedDelay)) 446ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen show_suppress_checkbox = true; 447ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 448ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Unlike for page alerts, navigations aren't a good signal for when to 449ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // resume showing alerts, so we can't reasonably stop showing them even if 450ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // the extension is spammy. 451ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen RunJavascriptMessageBox(profile_, this, frame_url, flags, message, 452ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen default_prompt, show_suppress_checkbox, reply_msg); 453ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 454ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // If we are suppressing messages, just reply as is if the user immediately 455ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // pressed "Cancel". 456ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen OnMessageBoxClosed(reply_msg, false, std::wstring()); 457ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::NativeWindow ExtensionHost::GetMessageBoxRootWindow() { 461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If we have a view, use that. 462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::NativeView native_view = GetNativeViewOfHost(); 463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (native_view) 464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return platform_util::GetTopLevel(native_view); 465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Otherwise, try the active tab's view. 467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Browser* browser = extension_function_dispatcher_->GetCurrentBrowser(true); 468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (browser) { 469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TabContents* active_tab = browser->GetSelectedTabContents(); 470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (active_tab) 471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return active_tab->view()->GetTopLevelNativeWindow(); 472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 47721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTabContents* ExtensionHost::AsTabContents() { 47821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return NULL; 47921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 48021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 48121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenExtensionHost* ExtensionHost::AsExtensionHost() { 48221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return this; 48321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 48421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHost::OnMessageBoxClosed(IPC::Message* reply_msg, 486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool success, 487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::wstring& prompt) { 488ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen last_javascript_message_dismissal_ = base::TimeTicks::Now(); 489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_view_host()->JavaScriptMessageBoxClosed(reply_msg, success, prompt); 490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 492ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ExtensionHost::SetSuppressMessageBoxes(bool suppress_message_boxes) { 493ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen suppress_javascript_messages_ = suppress_message_boxes; 494ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 495ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHost::Close(RenderViewHost* render_view_host) { 497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (extension_host_type_ == ViewType::EXTENSION_POPUP || 498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch extension_host_type_ == ViewType::EXTENSION_INFOBAR) { 499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::current()->Notify( 500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE, 501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Source<Profile>(profile_), 502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Details<ExtensionHost>(this)); 503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 506c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochRendererPreferences ExtensionHost::GetRendererPrefs(Profile* profile) const { 507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RendererPreferences preferences; 5083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 5093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TabContents* associated_contents = associated_tab_contents(); 5103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (associated_contents) 5113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick preferences = 5123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static_cast<RenderViewHostDelegate*>(associated_contents)-> 5133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GetRendererPrefs(profile); 5143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch renderer_preferences_util::UpdateFromSystemSettings(&preferences, profile); 516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return preferences; 517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 519c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochWebPreferences ExtensionHost::GetWebkitPrefs() { 520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile = render_view_host()->process()->profile(); 521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebPreferences webkit_prefs = 522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RenderViewHostDelegateHelper::GetWebkitPrefs(profile, 523dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen false); // is_web_ui 524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Extensions are trusted so we override any user preferences for disabling 525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // javascript or images. 526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch webkit_prefs.loads_images_automatically = true; 527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch webkit_prefs.javascript_enabled = true; 528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (extension_host_type_ == ViewType::EXTENSION_POPUP || 530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch extension_host_type_ == ViewType::EXTENSION_INFOBAR) 531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch webkit_prefs.allow_scripts_to_close_windows = true; 532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 53321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Disable anything that requires the GPU process for background pages. 53421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // See http://crbug.com/64512 and http://crbug.com/64841. 53521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (extension_host_type_ == ViewType::EXTENSION_BACKGROUND_PAGE) { 53621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen webkit_prefs.experimental_webgl_enabled = false; 53721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen webkit_prefs.accelerated_compositing_enabled = false; 53821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen webkit_prefs.accelerated_2d_canvas_enabled = false; 53921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 54021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(dcheng): incorporate this setting into kClipboardPermission check. 542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch webkit_prefs.javascript_can_access_clipboard = true; 543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(dcheng): check kClipboardPermission instead once it's implemented. 545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (extension_->HasApiPermission(Extension::kExperimentalPermission)) 546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch webkit_prefs.dom_paste_enabled = true; 547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return webkit_prefs; 548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 55072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ExtensionHost::ProcessWebUIMessage( 551ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const ExtensionHostMsg_DomMessage_Params& params) { 552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (extension_function_dispatcher_.get()) { 5533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick extension_function_dispatcher_->HandleRequest(params); 554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 557c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochRenderViewHostDelegate::View* ExtensionHost::GetViewDelegate() { 558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return this; 559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHost::CreateNewWindow( 562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int route_id, 56372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const ViewHostMsg_CreateWindow_Params& params) { 5643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // TODO(aa): Use the browser's profile if the extension is split mode 5653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // incognito. 5663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TabContents* new_contents = delegate_view_helper_.CreateNewWindow( 567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch route_id, 568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_view_host()->process()->profile(), 569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch site_instance(), 570ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ChromeWebUIFactory::GetInstance()->GetWebUIType( 571ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen render_view_host()->process()->profile(), url_), 572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch this, 57372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen params.window_container_type, 57472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen params.frame_name); 5753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 5763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TabContents* associated_contents = associated_tab_contents(); 5773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (associated_contents && associated_contents->delegate()) 5783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick associated_contents->delegate()->TabContentsCreated(new_contents); 579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHost::CreateNewWidget(int route_id, 582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebKit::WebPopupType popup_type) { 583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CreateNewWidgetInternal(route_id, popup_type); 584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 58672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ExtensionHost::CreateNewFullscreenWidget(int route_id) { 5873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NOTREACHED() 5883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << "ExtensionHost does not support showing full screen popups yet."; 5893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 5903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 591c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochRenderWidgetHostView* ExtensionHost::CreateNewWidgetInternal( 592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int route_id, WebKit::WebPopupType popup_type) { 593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return delegate_view_helper_.CreateNewWidget(route_id, popup_type, 594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch site_instance()->GetProcess()); 595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHost::ShowCreatedWindow(int route_id, 598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WindowOpenDisposition disposition, 599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const gfx::Rect& initial_pos, 600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool user_gesture) { 601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TabContents* contents = delegate_view_helper_.GetCreatedWindow(route_id); 602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!contents) 603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 605731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (disposition == NEW_POPUP) { 606731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Create a new Browser window of type TYPE_APP_POPUP. 607731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // (AddTabContents would otherwise create a window of type TYPE_POPUP). 608731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick Browser* browser = Browser::CreateForPopup(Browser::TYPE_APP_POPUP, 609731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick contents->profile(), 610731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick contents, 611731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick initial_pos); 612ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (user_gesture) 613ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen browser->window()->Show(); 614ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen else 615ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen browser->window()->ShowInactive(); 616513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return; 617513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 618513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 619513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // If the tab contents isn't a popup, it's a normal tab. We need to find a 620513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // home for it. This is typically a Browser, but it can also be some other 621513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // TabContentsDelegate in the case of ChromeFrame. 622513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 623513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // First, if the creating extension view was associated with a tab contents, 624513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // use that tab content's delegate. We must be careful here that the 625513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // associated tab contents has the same profile as the new tab contents. In 626513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // the case of extensions in 'spanning' incognito mode, they can mismatch. 627513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // We don't want to end up putting a normal tab into an incognito window, or 628513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // vice versa. 629513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch TabContents* associated_contents = associated_tab_contents(); 630513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (associated_contents && 631513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch associated_contents->profile() == contents->profile()) { 632ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen associated_contents->AddOrBlockNewContents( 633ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen contents, disposition, initial_pos, user_gesture); 634513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return; 635513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 636513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 637513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // If there's no associated tab contents, or it doesn't have a matching 638513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // profile, try finding an open window. Again, we must make sure to find a 639513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // window with the correct profile. 640513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch Browser* browser = BrowserList::FindBrowserWithType( 641731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick contents->profile(), 642731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick Browser::TYPE_NORMAL, 643731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick false); // Match incognito exactly. 644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 645513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // If there's no Browser open with the right profile, create a new one. 646513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!browser) { 647513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch browser = Browser::Create(contents->profile()); 648513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch browser->window()->Show(); 649731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 650ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen browser->AddTabContents(contents, disposition, initial_pos, user_gesture); 651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHost::ShowCreatedWidget(int route_id, 654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const gfx::Rect& initial_pos) { 655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ShowCreatedWidgetInternal(delegate_view_helper_.GetCreatedWidget(route_id), 656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch initial_pos); 657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ExtensionHost::ShowCreatedFullscreenWidget(int route_id) { 6603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NOTREACHED() 6613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << "ExtensionHost does not support showing full screen popups yet."; 6623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 6633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHost::ShowCreatedWidgetInternal( 665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RenderWidgetHostView* widget_host_view, 666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const gfx::Rect& initial_pos) { 667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Browser *browser = GetBrowser(); 668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(browser); 669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!browser) 670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser->BrowserRenderWidgetShowing(); 672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(erikkay): These two lines could be refactored with TabContentsView. 673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch widget_host_view->InitAsPopup(render_view_host()->view(), initial_pos); 674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch widget_host_view->GetRenderWidgetHost()->Init(); 675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHost::ShowContextMenu(const ContextMenuParams& params) { 678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(erikkay) Show a default context menu. 679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 681513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid ExtensionHost::ShowPopupMenu(const gfx::Rect& bounds, 682513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch int item_height, 683513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch double item_font_size, 684513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch int selected_item, 685513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const std::vector<WebMenuItem>& items, 686513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch bool right_aligned) { 687513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#if defined(OS_MACOSX) 688513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch PopupMenuHelper popup_menu_helper(render_view_host()); 689513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch popup_menu_helper.ShowPopupMenu(bounds, item_height, item_font_size, 690513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch selected_item, items, right_aligned); 691513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#else 692513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Only on Mac are select popup menus external. 693513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NOTREACHED(); 694513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#endif 695513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 696513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHost::StartDragging(const WebDropData& drop_data, 698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebDragOperationsMask operation_mask, 699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const SkBitmap& image, 700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const gfx::Point& image_offset) { 701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We're not going to do any drag & drop, but we have to tell the renderer the 702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // drag & drop ended, othewise the renderer thinks the drag operation is 703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // underway and mouse events won't work. See bug 34061. 704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(twiz) Implement drag & drop support for ExtensionHost instances. 705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // See feature issue 36288. 706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_view_host()->DragSourceSystemDragEnded(); 707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHost::UpdateDragCursor(WebDragOperation operation) { 710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHost::GotFocus() { 713dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(TOOLKIT_VIEWS) && !defined(TOUCH_UI) 714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Request focus so that the FocusManager has a focused view and can perform 715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // normally its key event processing (so that it lets tab key events go to the 716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // renderer). 717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch view()->RequestFocus(); 718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else 719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(port) 720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHost::TakeFocus(bool reverse) { 724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ExtensionHost::LostCapture() { 7273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 7283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 7293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ExtensionHost::Activate() { 7303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 7313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 7323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ExtensionHost::Deactivate() { 7333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 7343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ExtensionHost::PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event, 736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool* is_keyboard_shortcut) { 737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (extension_host_type_ == ViewType::EXTENSION_POPUP && 738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch event.type == NativeWebKeyboardEvent::RawKeyDown && 73972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen event.windowsKeyCode == ui::VKEY_ESCAPE) { 740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(is_keyboard_shortcut != NULL); 741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *is_keyboard_shortcut = true; 742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHost::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) { 747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (extension_host_type_ == ViewType::EXTENSION_POPUP) { 748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (event.type == NativeWebKeyboardEvent::RawKeyDown && 74972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen event.windowsKeyCode == ui::VKEY_ESCAPE) { 750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::current()->Notify( 751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE, 752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Source<Profile>(profile_), 753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Details<ExtensionHost>(this)); 754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UnhandledKeyboardEvent(event); 758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ExtensionHost::HandleMouseMove() { 761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN) 762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (view_.get()) 7633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick view_->HandleMouseMove(); 764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 766c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ExtensionHost::HandleMouseDown() { 7683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 7693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHost::HandleMouseLeave() { 771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN) 772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (view_.get()) 773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch view_->HandleMouseLeave(); 774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ExtensionHost::HandleMouseUp() { 7783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 7793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 7803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ExtensionHost::HandleMouseActivate() { 781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 783c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochViewType::Type ExtensionHost::GetRenderViewType() const { 784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return extension_host_type_; 785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 78772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool ExtensionHost::OnMessageReceived(const IPC::Message& message) { 78872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen bool handled = true; 78972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen IPC_BEGIN_MESSAGE_MAP(ExtensionHost, message) 79072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen IPC_MESSAGE_HANDLER(ViewHostMsg_RunFileChooser, OnRunFileChooser) 79172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen IPC_MESSAGE_UNHANDLED(handled = false) 79272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen IPC_END_MESSAGE_MAP() 79372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return handled; 79472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 79572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 79621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenconst GURL& ExtensionHost::GetURL() const { 79721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return url_; 79821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 79921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionHost::RenderViewCreated(RenderViewHost* render_view_host) { 801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (view_.get()) 802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch view_->RenderViewCreated(); 803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(mpcomplete): This is duplicated in DidNavigate, which means that 805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // we'll create 2 EFDs for the first navigation. We should try to find a 806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // better way to unify them. 807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // See http://code.google.com/p/chromium/issues/detail?id=18240 808c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch extension_function_dispatcher_.reset( 809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ExtensionFunctionDispatcher::Create(render_view_host, this, url_)); 810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 8113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (extension_host_type_ == ViewType::EXTENSION_POPUP || 812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch extension_host_type_ == ViewType::EXTENSION_INFOBAR) { 813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_view_host->EnablePreferredSizeChangedMode( 814c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kPreferredSizeWidth | kPreferredSizeHeightThisIsSlow); 815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 816c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint ExtensionHost::GetBrowserWindowID() const { 819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Hosts not attached to any browser window have an id of -1. This includes 820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // those mentioned below, and background pages. 821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int window_id = extension_misc::kUnknownWindowId; 8223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (extension_host_type_ == ViewType::EXTENSION_POPUP || 823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch extension_host_type_ == ViewType::EXTENSION_INFOBAR) { 824c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If the host is bound to a browser, then extract its window id. 825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Extensions hosted in ExternalTabContainer objects may not have 826c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // an associated browser. 82772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const Browser* browser = GetBrowser(); 828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (browser) 829c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch window_id = ExtensionTabUtil::GetWindowId(browser); 830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (extension_host_type_ != ViewType::EXTENSION_BACKGROUND_PAGE) { 831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 832c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return window_id; 834c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 83572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 83672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ExtensionHost::OnRunFileChooser( 83772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const ViewHostMsg_RunFileChooser_Params& params) { 83872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (file_select_helper_.get() == NULL) 83972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen file_select_helper_.reset(new FileSelectHelper(profile())); 840ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_select_helper_->RunFileChooser(render_view_host_, 841ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen associated_tab_contents(), params); 84272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 843