diff options
author | mpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-08 00:40:46 +0000 |
---|---|---|
committer | mpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-08 00:40:46 +0000 |
commit | ba79ad5d4a87264442ba2a25b2647f7f82484e8c (patch) | |
tree | b0cf7deae03f2fa5e15d1dba0ec01ba9e0bf2737 /chrome/browser/extensions | |
parent | aef2ab36c08e90d35af176b8333750e4242d0fc9 (diff) | |
download | chromium_src-ba79ad5d4a87264442ba2a25b2647f7f82484e8c.zip chromium_src-ba79ad5d4a87264442ba2a25b2647f7f82484e8c.tar.gz chromium_src-ba79ad5d4a87264442ba2a25b2647f7f82484e8c.tar.bz2 |
Have ExtensionHost use TabContents instead of RenderViewHost. This is part
of a larger refactor to eventually get rid of ExtensionHost as the container
for background pages.
BUG=84146
TEST=extensions (especially popups and infobars) should still work
Review URL: http://codereview.chromium.org/8476010
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@108954 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions')
11 files changed, 144 insertions, 517 deletions
diff --git a/chrome/browser/extensions/browser_action_apitest.cc b/chrome/browser/extensions/browser_action_apitest.cc index 39b6f9c..3b83f23 100644 --- a/chrome/browser/extensions/browser_action_apitest.cc +++ b/chrome/browser/extensions/browser_action_apitest.cc @@ -38,7 +38,7 @@ class BrowserActionApiTest : public ExtensionApiTest { bool OpenPopup(int index) { ResultCatcher catcher; ui_test_utils::WindowedNotificationObserver popup_observer( - chrome::NOTIFICATION_EXTENSION_POPUP_VIEW_READY, + content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME, content::NotificationService::AllSources()); GetBrowserActionsBar().Press(index); popup_observer.Wait(); diff --git a/chrome/browser/extensions/extension_browsertest.cc b/chrome/browser/extensions/extension_browsertest.cc index c49be53..17b83f6 100644 --- a/chrome/browser/extensions/extension_browsertest.cc +++ b/chrome/browser/extensions/extension_browsertest.cc @@ -44,9 +44,6 @@ void ExtensionBrowserTest::SetUpCommandLine(CommandLine* command_line) { // This enables DOM automation for tab contentses. EnableDOMAutomation(); - // This enables it for extension hosts. - ExtensionHost::EnableDOMAutomation(); - PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_); test_data_dir_ = test_data_dir_.AppendASCII("extensions"); diff --git a/chrome/browser/extensions/extension_browsertests_misc.cc b/chrome/browser/extensions/extension_browsertests_misc.cc index c6ef3a0..0981108 100644 --- a/chrome/browser/extensions/extension_browsertests_misc.cc +++ b/chrome/browser/extensions/extension_browsertests_misc.cc @@ -29,6 +29,7 @@ #include "content/public/browser/notification_service.h" #include "net/base/net_util.h" #include "net/test/test_server.h" +#include "webkit/glue/webpreferences.h" #if defined(TOOLKIT_VIEWS) #include "chrome/browser/ui/views/frame/browser_view.h" @@ -121,7 +122,9 @@ IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, WebKitPrefsBackgroundPage) { ExtensionProcessManager* manager = browser()->profile()->GetExtensionProcessManager(); ExtensionHost* host = FindHostWithPath(manager, "/backgroundpage.html", 1); - WebPreferences prefs = host->GetWebkitPrefs(); + WebPreferences prefs = + static_cast<RenderViewHostDelegate*>(host->host_contents())-> + GetWebkitPrefs(); ASSERT_FALSE(prefs.experimental_webgl_enabled); ASSERT_FALSE(prefs.accelerated_compositing_enabled); ASSERT_FALSE(prefs.accelerated_2d_canvas_enabled); diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc index 8b2eba1..f62929c 100644 --- a/chrome/browser/extensions/extension_host.cc +++ b/chrome/browser/extensions/extension_host.cc @@ -16,17 +16,12 @@ #include "chrome/browser/browser_shutdown.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_tab_util.h" -#include "chrome/browser/file_select_helper.h" -#include "chrome/browser/platform_util.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/renderer_preferences_util.h" -#include "chrome/browser/tabs/tab_strip_model.h" #include "chrome/browser/ui/app_modal_dialogs/message_box_handler.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" -#include "chrome/browser/ui/webui/chrome_web_ui_factory.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_notification_types.h" #include "chrome/common/extensions/extension.h" @@ -39,24 +34,18 @@ #include "content/browser/renderer_host/browser_render_process_host.h" #include "content/browser/renderer_host/render_process_host.h" #include "content/browser/renderer_host/render_view_host.h" -#include "content/browser/renderer_host/render_widget_host.h" -#include "content/browser/renderer_host/render_widget_host_view.h" -#include "content/browser/site_instance.h" -#include "content/browser/tab_contents/popup_menu_helper_mac.h" #include "content/browser/tab_contents/tab_contents.h" #include "content/browser/tab_contents/tab_contents_view.h" #include "content/public/browser/notification_service.h" #include "content/common/view_messages.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/native_web_keyboard_event.h" -#include "content/public/common/bindings_policy.h" #include "grit/browser_resources.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" #include "ui/base/keycodes/keyboard_codes.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" -#include "webkit/glue/context_menu.h" #if defined(TOOLKIT_VIEWS) #include "views/widget/widget.h" @@ -65,9 +54,6 @@ using WebKit::WebDragOperation; using WebKit::WebDragOperationsMask; -// static -bool ExtensionHost::enable_dom_automation_ = false; - // Helper class that rate-limits the creation of renderer processes for // ExtensionHosts, to avoid blocking the UI. class ExtensionHost::ProcessCreationQueue { @@ -138,20 +124,21 @@ ExtensionHost::ExtensionHost(const Extension* extension, site_instance->browsing_instance()->browser_context())), did_stop_loading_(false), document_element_available_(false), - url_(url), + initial_url_(url), ALLOW_THIS_IN_INITIALIZER_LIST( extension_function_dispatcher_(profile_, this)), extension_host_type_(host_type), associated_tab_contents_(NULL) { - render_view_host_ = new RenderViewHost(site_instance, this, MSG_ROUTING_NONE, - NULL); - if (enable_dom_automation_) - render_view_host_->AllowBindings(content::BINDINGS_POLICY_DOM_AUTOMATION); + host_contents_.reset(new TabContents( + profile_, site_instance, MSG_ROUTING_NONE, NULL, NULL)); + TabContentsObserver::Observe(host_contents_.get()); + host_contents_->set_delegate(this); + host_contents_->set_view_type(host_type); // Listen for when the render process' handle is available so we can add it // to the task manager then. registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED, - content::Source<RenderProcessHost>(render_process_host())); + content::NotificationService::AllBrowserContextsAndSources()); // Listen for when an extension is unloaded from the same profile, as it may // be the same extension that this points to. registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, @@ -164,10 +151,9 @@ ExtensionHost::ExtensionHost(const Extension* extension, : extension_(extension), extension_id_(extension->id()), profile_(NULL), - render_view_host_(NULL), did_stop_loading_(false), document_element_available_(false), - url_(GURL()), + initial_url_(GURL()), ALLOW_THIS_IN_INITIALIZER_LIST( extension_function_dispatcher_(profile_, this)), extension_host_type_(host_type), @@ -180,10 +166,6 @@ ExtensionHost::~ExtensionHost() { content::Source<Profile>(profile_), content::Details<ExtensionHost>(this)); ProcessCreationQueue::GetInstance()->Remove(this); - GetJavaScriptDialogCreatorInstance()->ResetJavaScriptState(this); - // render_view_host_ may be NULL in unit tests. - if (render_view_host_) - render_view_host_->Shutdown(); // deletes render_view_host } void ExtensionHost::CreateView(Browser* browser) { @@ -209,20 +191,20 @@ TabContents* ExtensionHost::GetAssociatedTabContents() const { } RenderProcessHost* ExtensionHost::render_process_host() const { - return render_view_host_->process(); + return host_contents()->GetRenderProcessHost(); } -SiteInstance* ExtensionHost::site_instance() const { - return render_view_host_->site_instance(); +RenderViewHost* ExtensionHost::render_view_host() const { + // TODO(mpcomplete): This can be NULL. How do we handle that? + return host_contents()->render_view_host(); } bool ExtensionHost::IsRenderViewLive() const { - return render_view_host_->IsRenderViewLive(); + return render_view_host()->IsRenderViewLive(); } -void ExtensionHost::CreateRenderViewSoon(RenderWidgetHostView* host_view) { - render_view_host_->SetView(host_view); - if (render_view_host_->process()->HasConnection()) { +void ExtensionHost::CreateRenderViewSoon() { + if (render_process_host()->HasConnection()) { // If the process is already started, go ahead and initialize the RenderView // synchronously. The process creation is the real meaty part that we want // to defer. @@ -233,25 +215,10 @@ void ExtensionHost::CreateRenderViewSoon(RenderWidgetHostView* host_view) { } void ExtensionHost::CreateRenderViewNow() { - render_view_host_->CreateRenderView(string16()); - if (extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_POPUP || - extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_DIALOG || - extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_INFOBAR) { - // If the host is bound to a browser, then extract its window id. - // Extensions hosted in ExternalTabContainer objects may not have - // an associated browser. - const Browser* browser = GetBrowser(); - if (browser && render_view_host_) { - render_view_host_->Send(new ExtensionMsg_UpdateBrowserWindowId( - render_view_host_->routing_id(), - ExtensionTabUtil::GetWindowId(browser))); - } - } - NavigateToURL(url_); + LoadInitialURL(); DCHECK(IsRenderViewLive()); if (is_background_page()) - profile_->GetExtensionService()->DidCreateRenderViewForBackgroundPage( - this); + profile_->GetExtensionService()->DidCreateRenderViewForBackgroundPage(this); } const Browser* ExtensionHost::GetBrowser() const { @@ -266,17 +233,11 @@ gfx::NativeView ExtensionHost::GetNativeViewOfHost() { return view() ? view()->native_view() : NULL; } -void ExtensionHost::NavigateToURL(const GURL& url) { - // Prevent explicit navigation to another extension id's pages. - // This method is only called by some APIs, so we still need to protect - // DidNavigate below (location = ""). - if (url.SchemeIs(chrome::kExtensionScheme) && url.host() != extension_id()) { - // TODO(erikkay) communicate this back to the caller? - return; - } - - url_ = url; +const GURL& ExtensionHost::GetURL() const { + return host_contents()->GetURL(); +} +void ExtensionHost::LoadInitialURL() { if (!is_background_page() && !profile_->GetExtensionService()->IsBackgroundPageReady(extension_)) { // Make sure the background page loads before any others. @@ -285,7 +246,8 @@ void ExtensionHost::NavigateToURL(const GURL& url) { return; } - render_view_host_->NavigateToURL(url_); + host_contents_->controller().LoadURL( + initial_url_, GURL(), content::PAGE_TRANSITION_LINK, std::string()); } void ExtensionHost::Observe(int type, @@ -295,13 +257,16 @@ void ExtensionHost::Observe(int type, case chrome::NOTIFICATION_EXTENSION_BACKGROUND_PAGE_READY: DCHECK(profile_->GetExtensionService()-> IsBackgroundPageReady(extension_)); - NavigateToURL(url_); + LoadInitialURL(); break; case content::NOTIFICATION_RENDERER_PROCESS_CREATED: - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_EXTENSION_PROCESS_CREATED, - content::Source<Profile>(profile_), - content::Details<ExtensionHost>(this)); + if (content::Source<RenderProcessHost>(source).ptr() == + render_process_host()) { + content::NotificationService::current()->Notify( + chrome::NOTIFICATION_EXTENSION_PROCESS_CREATED, + content::Source<Profile>(profile_), + content::Details<ExtensionHost>(this)); + } break; case chrome::NOTIFICATION_EXTENSION_UNLOADED: // The extension object will be deleted after this notification has been @@ -319,14 +284,13 @@ void ExtensionHost::Observe(int type, } } -void ExtensionHost::UpdatePreferredSize(const gfx::Size& new_size) { +void ExtensionHost::UpdatePreferredSize(TabContents* source, + const gfx::Size& pref_size) { if (view_.get()) - view_->UpdatePreferredSize(new_size); + view_->UpdatePreferredSize(pref_size); } -void ExtensionHost::RenderViewGone(RenderViewHost* render_view_host, - base::TerminationStatus status, - int error_code) { +void ExtensionHost::RenderViewGone() { // During browser shutdown, we may use sudden termination on an extension // process, so it is expected to lose our connection to the render view. // Do nothing. @@ -345,22 +309,12 @@ void ExtensionHost::RenderViewGone(RenderViewHost* render_view_host, // TODO(aa): This is suspicious. There can be multiple views in an extension, // and they aren't all going to use ExtensionHost. This should be in someplace // more central, like EPM maybe. - DCHECK_EQ(render_view_host_, render_view_host); content::NotificationService::current()->Notify( chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED, content::Source<Profile>(profile_), content::Details<ExtensionHost>(this)); } -void ExtensionHost::DidNavigate(RenderViewHost* render_view_host, - const ViewHostMsg_FrameNavigate_Params& params) { - // We only care when the outer frame changes. - if (!content::PageTransitionIsMainFrame(params.transition)) - return; - - url_ = params.url; -} - void ExtensionHost::InsertInfobarCSS() { DCHECK(!is_background_page()); @@ -408,7 +362,7 @@ void ExtensionHost::DidStopLoading() { } } -void ExtensionHost::DocumentAvailableInMainFrame(RenderViewHost* rvh) { +void ExtensionHost::DocumentAvailableInMainFrame() { // If the document has already been marked as available for this host, then // bail. No need for the redundant setup. http://crbug.com/31170 if (document_element_available_) @@ -428,77 +382,7 @@ void ExtensionHost::DocumentAvailableInMainFrame(RenderViewHost* rvh) { } } -void ExtensionHost::DocumentOnLoadCompletedInMainFrame(RenderViewHost* rvh, - int32 page_id) { - if (chrome::VIEW_TYPE_EXTENSION_POPUP == GetRenderViewType()) { - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_EXTENSION_POPUP_VIEW_READY, - content::Source<Profile>(profile_), - content::Details<ExtensionHost>(this)); - } -} - -void ExtensionHost::RunJavaScriptMessage(const RenderViewHost* rvh, - const string16& message, - const string16& default_prompt, - const GURL& frame_url, - const int flags, - IPC::Message* reply_msg, - bool* did_suppress_message) { - bool suppress_this_message = false; - - string16 title; - if (extension_->location() == Extension::COMPONENT) - title = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); - else - title = UTF8ToUTF16(extension_->name()); - - GetJavaScriptDialogCreatorInstance()->RunJavaScriptDialog( - this, - content::JavaScriptDialogCreator::DIALOG_TITLE_PLAIN_STRING, - title, - flags, - message, - default_prompt, - reply_msg, - &suppress_this_message); - - if (suppress_this_message) { - // If we are suppressing messages, just reply as if the user immediately - // pressed "Cancel". - OnDialogClosed(reply_msg, false, string16()); - } - - *did_suppress_message = suppress_this_message; -} - -gfx::NativeWindow ExtensionHost::GetDialogRootWindow() { - // If we have a view, use that. - gfx::NativeView native_view = GetNativeViewOfHost(); - if (native_view) - return platform_util::GetTopLevel(native_view); - - // Otherwise, try the active tab's view. - Browser* browser = extension_function_dispatcher_.GetCurrentBrowser( - render_view_host_, true); - if (browser) { - TabContents* active_tab = browser->GetSelectedTabContents(); - if (active_tab) - return active_tab->view()->GetTopLevelNativeWindow(); - } - - return NULL; -} - -void ExtensionHost::OnDialogClosed(IPC::Message* reply_msg, - bool success, - const string16& user_input) { - render_view_host()->JavaScriptDialogClosed(reply_msg, - success, - user_input); -} - -void ExtensionHost::Close(RenderViewHost* render_view_host) { +void ExtensionHost::CloseContents(TabContents* contents) { if (extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_POPUP || extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_DIALOG || extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE || @@ -510,40 +394,6 @@ void ExtensionHost::Close(RenderViewHost* render_view_host) { } } -content::RendererPreferences ExtensionHost::GetRendererPrefs( - content::BrowserContext* browser_context) const { - Profile* profile = Profile::FromBrowserContext(browser_context); - content::RendererPreferences preferences; - - TabContents* associated_contents = GetAssociatedTabContents(); - if (associated_contents) - preferences = - static_cast<RenderViewHostDelegate*>(associated_contents)-> - GetRendererPrefs(profile); - - renderer_preferences_util::UpdateFromSystemSettings(&preferences, profile); - return preferences; -} - -WebPreferences ExtensionHost::GetWebkitPrefs() { - WebPreferences webkit_prefs = - RenderViewHostDelegateHelper::GetWebkitPrefs(render_view_host()); - - // Disable anything that requires the GPU process for background pages. - // See http://crbug.com/64512 and http://crbug.com/64841. - if (extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { - webkit_prefs.experimental_webgl_enabled = false; - webkit_prefs.accelerated_compositing_enabled = false; - webkit_prefs.accelerated_2d_canvas_enabled = false; - } - - return webkit_prefs; -} - -RenderViewHostDelegate::View* ExtensionHost::GetViewDelegate() { - return this; -} - bool ExtensionHost::PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) { if (extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_POPUP && @@ -569,85 +419,64 @@ void ExtensionHost::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) { UnhandledKeyboardEvent(event); } -void ExtensionHost::HandleMouseMove() { -#if defined(OS_WIN) - if (view_.get()) - view_->HandleMouseMove(); -#endif -} - -void ExtensionHost::HandleMouseDown() { -} - -void ExtensionHost::HandleMouseLeave() { -#if defined(OS_WIN) - if (view_.get()) - view_->HandleMouseLeave(); +// TODO(mpcomplete): is this necessary? +void ExtensionHost::TabContentsFocused(TabContents* contents) { +#if defined(TOOLKIT_VIEWS) && !defined(TOUCH_UI) + // Request focus so that the FocusManager has a focused view and can perform + // normally its key event processing (so that it lets tab key events go to the + // renderer). + view()->RequestFocus(); +#else + // TODO(port) #endif } -void ExtensionHost::HandleMouseUp() { -} - -void ExtensionHost::HandleMouseActivate() { +bool ExtensionHost::OnMessageReceived(const IPC::Message& message) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(ExtensionHost, message) + IPC_MESSAGE_HANDLER(ExtensionHostMsg_Request, OnRequest) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; } -void ExtensionHost::RunFileChooser( - RenderViewHost* render_view_host, - const ViewHostMsg_RunFileChooser_Params& params) { - // FileSelectHelper adds a reference to itself and only releases it after - // sending the result message. It won't be destroyed when this reference - // goes out of scope. - scoped_refptr<FileSelectHelper> file_select_helper( - new FileSelectHelper(profile())); - file_select_helper->RunFileChooser(render_view_host, - GetAssociatedTabContents(), - params); +void ExtensionHost::OnRequest(const ExtensionHostMsg_Request_Params& params) { + extension_function_dispatcher_.Dispatch(params, render_view_host()); } -void ExtensionHost::CreateNewWindow( - int route_id, - const ViewHostMsg_CreateWindow_Params& params) { - // TODO(aa): Use the browser's profile if the extension is split mode - // incognito. - Profile* profile = Profile::FromBrowserContext( - render_view_host()->process()->browser_context()); - TabContents* new_contents = delegate_view_helper_.CreateNewWindow( - route_id, - profile, - site_instance(), - ChromeWebUIFactory::GetInstance()->GetWebUIType( - render_view_host()->process()->browser_context(), url_), - this, - params.window_container_type, - params.frame_name); - - TabContents* associated_contents = GetAssociatedTabContents(); - if (associated_contents && associated_contents->delegate()) - associated_contents->delegate()->TabContentsCreated(new_contents); -} +void ExtensionHost::RenderViewCreated(RenderViewHost* render_view_host) { + if (view_.get()) + view_->RenderViewCreated(); -void ExtensionHost::CreateNewWidget(int route_id, - WebKit::WebPopupType popup_type) { - CreateNewWidgetInternal(route_id, popup_type); -} + if (extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_POPUP || + extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_INFOBAR) { + render_view_host->EnablePreferredSizeMode( + kPreferredSizeWidth | kPreferredSizeHeightThisIsSlow); + } -void ExtensionHost::CreateNewFullscreenWidget(int route_id) { - NOTREACHED() - << "ExtensionHost does not support showing full screen popups yet."; + // If the host is bound to a browser, then extract its window id. + // Extensions hosted in ExternalTabContainer objects may not have + // an associated browser. + const Browser* browser = GetBrowser(); + if (browser) { + render_view_host->Send(new ExtensionMsg_UpdateBrowserWindowId( + render_view_host->routing_id(), + ExtensionTabUtil::GetWindowId(browser))); + } } -RenderWidgetHostView* ExtensionHost::CreateNewWidgetInternal( - int route_id, WebKit::WebPopupType popup_type) { - return delegate_view_helper_.CreateNewWidget(route_id, popup_type, - site_instance()->GetProcess()); +content::JavaScriptDialogCreator* ExtensionHost::GetJavaScriptDialogCreator() { + return GetJavaScriptDialogCreatorInstance(); } -void ExtensionHost::ShowCreatedWindow(int route_id, - WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, - bool user_gesture) { - TabContents* contents = delegate_view_helper_.GetCreatedWindow(route_id); +void ExtensionHost::AddNewContents(TabContents* source, + TabContents* new_contents, + WindowOpenDisposition disposition, + const gfx::Rect& initial_pos, + bool user_gesture) { + // TODO(mpcomplete): is all this necessary? Maybe we can just call the + // brower's delegate, and fall back to browser::Navigate if browser is NULL. + TabContents* contents = new_contents; if (!contents) return; Profile* profile = Profile::FromBrowserContext(contents->browser_context()); @@ -673,10 +502,6 @@ void ExtensionHost::ShowCreatedWindow(int route_id, return; } - // If the tab contents isn't a popup, it's a normal tab. We need to find a - // home for it. This is typically a Browser, but it can also be some other - // TabContentsDelegate in the case of ChromeFrame. - // First, if the creating extension view was associated with a tab contents, // use that tab content's delegate. We must be careful here that the // associated tab contents has the same profile as the new tab contents. In @@ -695,7 +520,7 @@ void ExtensionHost::ShowCreatedWindow(int route_id, // profile, try finding an open window. Again, we must make sure to find a // window with the correct profile. Browser* browser = BrowserList::FindTabbedBrowser( - profile, false); // Match incognito exactly. + profile, false); // Match incognito exactly. // If there's no Browser open with the right profile, create a new one. if (!browser) { @@ -704,108 +529,3 @@ void ExtensionHost::ShowCreatedWindow(int route_id, } browser->AddTabContents(contents, disposition, initial_pos, user_gesture); } - -void ExtensionHost::ShowCreatedWidget(int route_id, - const gfx::Rect& initial_pos) { - ShowCreatedWidgetInternal(delegate_view_helper_.GetCreatedWidget(route_id), - initial_pos); -} - -void ExtensionHost::ShowCreatedFullscreenWidget(int route_id) { - NOTREACHED() - << "ExtensionHost does not support showing full screen popups yet."; -} - -void ExtensionHost::ShowCreatedWidgetInternal( - RenderWidgetHostView* widget_host_view, - const gfx::Rect& initial_pos) { - Browser *browser = GetBrowser(); - DCHECK(browser); - if (!browser) - return; - browser->BrowserRenderWidgetShowing(); - // TODO(erikkay): These two lines could be refactored with TabContentsView. - widget_host_view->InitAsPopup(render_view_host()->view(), initial_pos); - widget_host_view->GetRenderWidgetHost()->Init(); -} - -void ExtensionHost::ShowContextMenu(const ContextMenuParams& params) { - // TODO(erikkay) Show a default context menu. -} - -void ExtensionHost::ShowPopupMenu(const gfx::Rect& bounds, - int item_height, - double item_font_size, - int selected_item, - const std::vector<WebMenuItem>& items, - bool right_aligned) { -#if defined(OS_MACOSX) - PopupMenuHelper popup_menu_helper(render_view_host()); - popup_menu_helper.ShowPopupMenu(bounds, item_height, item_font_size, - selected_item, items, right_aligned); -#else - // Only on Mac are select popup menus external. - NOTREACHED(); -#endif -} - -void ExtensionHost::StartDragging(const WebDropData& drop_data, - WebDragOperationsMask operation_mask, - const SkBitmap& image, - const gfx::Point& image_offset) { - // We're not going to do any drag & drop, but we have to tell the renderer the - // drag & drop ended, othewise the renderer thinks the drag operation is - // underway and mouse events won't work. See bug 34061. - // TODO(twiz) Implement drag & drop support for ExtensionHost instances. - // See feature issue 36288. - render_view_host()->DragSourceSystemDragEnded(); -} - -void ExtensionHost::UpdateDragCursor(WebDragOperation operation) { -} - -void ExtensionHost::GotFocus() { -#if defined(TOOLKIT_VIEWS) && !defined(TOUCH_UI) - // Request focus so that the FocusManager has a focused view and can perform - // normally its key event processing (so that it lets tab key events go to the - // renderer). - view()->RequestFocus(); -#else - // TODO(port) -#endif -} - -void ExtensionHost::TakeFocus(bool reverse) { -} - -content::ViewType ExtensionHost::GetRenderViewType() const { - return extension_host_type_; -} - -bool ExtensionHost::OnMessageReceived(const IPC::Message& message) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(ExtensionHost, message) - IPC_MESSAGE_HANDLER(ExtensionHostMsg_Request, OnRequest) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; -} - -void ExtensionHost::OnRequest(const ExtensionHostMsg_Request_Params& params) { - extension_function_dispatcher_.Dispatch(params, render_view_host_); -} - -const GURL& ExtensionHost::GetURL() const { - return url_; -} - -void ExtensionHost::RenderViewCreated(RenderViewHost* render_view_host) { - if (view_.get()) - view_->RenderViewCreated(); - - if (extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_POPUP || - extension_host_type_ == chrome::VIEW_TYPE_EXTENSION_INFOBAR) { - render_view_host->EnablePreferredSizeMode( - kPreferredSizeWidth | kPreferredSizeHeightThisIsSlow); - } -} diff --git a/chrome/browser/extensions/extension_host.h b/chrome/browser/extensions/extension_host.h index 0adc57d..26afd98 100644 --- a/chrome/browser/extensions/extension_host.h +++ b/chrome/browser/extensions/extension_host.h @@ -12,11 +12,12 @@ #include "base/memory/scoped_ptr.h" #include "base/perftimer.h" #include "chrome/browser/extensions/extension_function_dispatcher.h" -#include "chrome/browser/tab_contents/render_view_host_delegate_helper.h" #include "content/browser/javascript_dialogs.h" -#include "content/browser/renderer_host/render_view_host_delegate.h" +#include "content/browser/tab_contents/tab_contents_delegate.h" +#include "content/browser/tab_contents/tab_contents_observer.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" +#include "content/public/common/view_types.h" #if defined(TOOLKIT_VIEWS) #include "chrome/browser/ui/views/extensions/extension_view.h" @@ -39,17 +40,13 @@ struct WebPreferences; // It handles setting up the renderer process, if needed, with special // privileges available to extensions. It may have a view to be shown in the // browser UI, or it may be hidden. -class ExtensionHost : public RenderViewHostDelegate, - public RenderViewHostDelegate::View, +class ExtensionHost : public TabContentsDelegate, + public TabContentsObserver, public ExtensionFunctionDispatcher::Delegate, - public content::NotificationObserver, - public content::JavaScriptDialogDelegate { + public content::NotificationObserver { public: class ProcessCreationQueue; - // Enable DOM automation in created render view hosts. - static void EnableDOMAutomation() { enable_dom_automation_ = true; } - ExtensionHost(const Extension* extension, SiteInstance* site_instance, const GURL& url, content::ViewType host_type); virtual ~ExtensionHost(); @@ -74,9 +71,9 @@ class ExtensionHost : public RenderViewHostDelegate, const Extension* extension() const { return extension_; } const std::string& extension_id() const { return extension_id_; } - RenderViewHost* render_view_host() const { return render_view_host_; } + TabContents* host_contents() const { return host_contents_.get(); } + RenderViewHost* render_view_host() const; RenderProcessHost* render_process_host() const; - SiteInstance* site_instance() const; bool did_stop_loading() const { return did_stop_loading_; } bool document_element_available() const { return document_element_available_; @@ -84,9 +81,8 @@ class ExtensionHost : public RenderViewHostDelegate, Profile* profile() const { return profile_; } - content::ViewType extension_host_type() const { - return extension_host_type_; - } + content::ViewType extension_host_type() const { return extension_host_type_; } + const GURL& GetURL() const; // ExtensionFunctionDispatcher::Delegate virtual TabContents* GetAssociatedTabContents() const OVERRIDE; @@ -100,10 +96,7 @@ class ExtensionHost : public RenderViewHostDelegate, // Prepares to initializes our RenderViewHost by creating its RenderView and // navigating to this host's url. Uses host_view for the RenderViewHost's view // (can be NULL). This happens delayed to avoid locking the UI. - void CreateRenderViewSoon(RenderWidgetHostView* host_view); - - // Sets |url_| and navigates |render_view_host_|. - void NavigateToURL(const GURL& url); + void CreateRenderViewSoon(); // Insert a default style sheet for Extension Infobars. void InsertInfobarCSS(); @@ -112,116 +105,48 @@ class ExtensionHost : public RenderViewHostDelegate, // |size_limit| in both width and height. void DisableScrollbarsForSmallWindows(const gfx::Size& size_limit); - // RenderViewHostDelegate implementation. + // TabContentsObserver virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; - virtual const GURL& GetURL() const OVERRIDE; virtual void RenderViewCreated(RenderViewHost* render_view_host) OVERRIDE; - virtual content::ViewType GetRenderViewType() const OVERRIDE; - virtual void RenderViewGone(RenderViewHost* render_view_host, - base::TerminationStatus status, - int error_code) OVERRIDE; - virtual void DidNavigate( - RenderViewHost* render_view_host, - const ViewHostMsg_FrameNavigate_Params& params) OVERRIDE; + virtual void RenderViewGone() OVERRIDE; + virtual void DocumentAvailableInMainFrame() OVERRIDE; virtual void DidStopLoading() OVERRIDE; - virtual void DocumentAvailableInMainFrame( - RenderViewHost* render_view_host) OVERRIDE; - virtual void DocumentOnLoadCompletedInMainFrame( - RenderViewHost* render_view_host, - int32 page_id) OVERRIDE; - virtual RenderViewHostDelegate::View* GetViewDelegate() OVERRIDE; - virtual WebPreferences GetWebkitPrefs() OVERRIDE; - virtual void RunJavaScriptMessage(const RenderViewHost* rvh, - const string16& message, - const string16& default_prompt, - const GURL& frame_url, - const int flags, - IPC::Message* reply_msg, - bool* did_suppress_message) OVERRIDE; - virtual void Close(RenderViewHost* render_view_host) OVERRIDE; - virtual content::RendererPreferences GetRendererPrefs( - content::BrowserContext* browser_context) const OVERRIDE; + + // TabContentsDelegate virtual bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) OVERRIDE; virtual void HandleKeyboardEvent(const NativeWebKeyboardEvent& event) OVERRIDE; - virtual void HandleMouseMove() OVERRIDE; - virtual void HandleMouseDown() OVERRIDE; - virtual void HandleMouseLeave() OVERRIDE; - virtual void HandleMouseUp() OVERRIDE; - virtual void HandleMouseActivate() OVERRIDE; - virtual void RunFileChooser(RenderViewHost* render_view_host, - const ViewHostMsg_RunFileChooser_Params& params); - virtual void UpdatePreferredSize(const gfx::Size& new_size); - - // RenderViewHostDelegate::View - virtual void CreateNewWindow( - int route_id, - const ViewHostMsg_CreateWindow_Params& params) OVERRIDE; - virtual void CreateNewWidget(int route_id, - WebKit::WebPopupType popup_type) OVERRIDE; - virtual void CreateNewFullscreenWidget(int route_id) OVERRIDE; - virtual void ShowCreatedWindow(int route_id, - WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, - bool user_gesture) OVERRIDE; - virtual void ShowCreatedWidget(int route_id, - const gfx::Rect& initial_pos) OVERRIDE; - virtual void ShowCreatedFullscreenWidget(int route_id) OVERRIDE; - virtual void ShowContextMenu(const ContextMenuParams& params) OVERRIDE; - virtual void ShowPopupMenu(const gfx::Rect& bounds, - int item_height, - double item_font_size, - int selected_item, - const std::vector<WebMenuItem>& items, - bool right_aligned) OVERRIDE; - virtual void StartDragging(const WebDropData& drop_data, - WebKit::WebDragOperationsMask allowed_operations, - const SkBitmap& image, - const gfx::Point& image_offset) OVERRIDE; - virtual void UpdateDragCursor(WebKit::WebDragOperation operation) OVERRIDE; - virtual void GotFocus() OVERRIDE; - virtual void TakeFocus(bool reverse) OVERRIDE; + virtual void UpdatePreferredSize(TabContents* source, + const gfx::Size& pref_size) OVERRIDE; + virtual content::JavaScriptDialogCreator* GetJavaScriptDialogCreator() + OVERRIDE; + virtual void AddNewContents(TabContents* source, + TabContents* new_contents, + WindowOpenDisposition disposition, + const gfx::Rect& initial_pos, + bool user_gesture) OVERRIDE; + virtual void TabContentsFocused(TabContents* contents) OVERRIDE; + virtual void CloseContents(TabContents* contents) OVERRIDE; // content::NotificationObserver virtual void Observe(int type, const content::NotificationSource& source, const content::NotificationDetails& details) OVERRIDE; - // Overridden from content::JavaScriptDialogDelegate: - virtual void OnDialogClosed(IPC::Message* reply_msg, - bool success, - const string16& user_input) OVERRIDE; - virtual gfx::NativeWindow GetDialogRootWindow() OVERRIDE; - protected: // This should only be used by unit tests. ExtensionHost(const Extension* extension, content::ViewType host_type); - // Internal functions used to support the CreateNewWidget() method. If a - // platform requires plugging into widget creation at a lower level, then a - // subclass might want to override these functions, but otherwise they should - // be fine just implementing RenderWidgetHostView::InitAsPopup(). - // - // The Create function returns the newly created widget so it can be - // associated with the given route. When the widget needs to be shown later, - // we'll look it up again and pass the object to the Show functions rather - // than the route ID. - virtual RenderWidgetHostView* CreateNewWidgetInternal( - int route_id, - WebKit::WebPopupType popup_type); - virtual void ShowCreatedWidgetInternal(RenderWidgetHostView* widget_host_view, - const gfx::Rect& initial_pos); private: friend class ProcessCreationQueue; - // Whether to allow DOM automation for created RenderViewHosts. This is used - // for testing. - static bool enable_dom_automation_; - // Actually create the RenderView for this host. See CreateRenderViewSoon. void CreateRenderViewNow(); + // Navigates to the initial page. + void LoadInitialURL(); + // Const version of below function. const Browser* GetBrowser() const; @@ -260,10 +185,7 @@ class ExtensionHost : public RenderViewHostDelegate, #endif // The host for our HTML content. - RenderViewHost* render_view_host_; - - // Common implementations of some RenderViewHostDelegate::View methods. - RenderViewHostDelegateViewHelper delegate_view_helper_; + scoped_ptr<TabContents> host_contents_; // Whether the RenderWidget has reported that it has stopped loading. bool did_stop_loading_; @@ -271,8 +193,8 @@ class ExtensionHost : public RenderViewHostDelegate, // True if the main frame has finished parsing. bool document_element_available_; - // The URL being hosted. - GURL url_; + // The original URL of the page being hosted. + GURL initial_url_; content::NotificationRegistrar registrar_; diff --git a/chrome/browser/extensions/extension_host_mac.h b/chrome/browser/extensions/extension_host_mac.h index d688f9f4..2425d82 100644 --- a/chrome/browser/extensions/extension_host_mac.h +++ b/chrome/browser/extensions/extension_host_mac.h @@ -10,18 +10,14 @@ class RenderWidgetHostView; +// TODO(mpcomplete): I don't know what this does or if it is needed anymore, +// now that ExtensionHost is restructured to rely on TabContents. class ExtensionHostMac : public ExtensionHost { public: ExtensionHostMac(const Extension* extension, SiteInstance* site_instance, const GURL& url, content::ViewType host_type) : ExtensionHost(extension, site_instance, url, host_type) {} virtual ~ExtensionHostMac(); - protected: - virtual RenderWidgetHostView* CreateNewWidgetInternal( - int route_id, - WebKit::WebPopupType popup_type); - virtual void ShowCreatedWidgetInternal(RenderWidgetHostView* widget_host_view, - const gfx::Rect& initial_pos); private: virtual void UnhandledKeyboardEvent(const NativeWebKeyboardEvent& event); diff --git a/chrome/browser/extensions/extension_host_mac.mm b/chrome/browser/extensions/extension_host_mac.mm index 64c5d92..424db46 100644 --- a/chrome/browser/extensions/extension_host_mac.mm +++ b/chrome/browser/extensions/extension_host_mac.mm @@ -22,33 +22,6 @@ ExtensionHostMac::~ExtensionHostMac() { } } -RenderWidgetHostView* ExtensionHostMac::CreateNewWidgetInternal( - int route_id, - WebKit::WebPopupType popup_type) { - // A RenderWidgetHostViewMac has lifetime scoped to the view. We'll retain it - // to allow it to survive the trip without being hosed. - RenderWidgetHostView* widget_view = - ExtensionHost::CreateNewWidgetInternal(route_id, popup_type); - RenderWidgetHostViewMac* widget_view_mac = - static_cast<RenderWidgetHostViewMac*>(widget_view); - [widget_view_mac->native_view() retain]; - - return widget_view; -} - -void ExtensionHostMac::ShowCreatedWidgetInternal( - RenderWidgetHostView* widget_host_view, - const gfx::Rect& initial_pos) { - ExtensionHost::ShowCreatedWidgetInternal(widget_host_view, initial_pos); - - // A RenderWidgetHostViewMac has lifetime scoped to the view. Now that it's - // properly embedded (or purposefully ignored) we can release the reference we - // took in CreateNewWidgetInternal(). - RenderWidgetHostViewMac* widget_view_mac = - static_cast<RenderWidgetHostViewMac*>(widget_host_view); - [widget_view_mac->native_view() release]; -} - void ExtensionHostMac::UnhandledKeyboardEvent( const NativeWebKeyboardEvent& event) { if (event.skip_in_browser || event.type == NativeWebKeyboardEvent::Char || diff --git a/chrome/browser/extensions/extension_process_manager.cc b/chrome/browser/extensions/extension_process_manager.cc index b79a35e..5cd90ed 100644 --- a/chrome/browser/extensions/extension_process_manager.cc +++ b/chrome/browser/extensions/extension_process_manager.cc @@ -206,7 +206,7 @@ void ExtensionProcessManager::CreateBackgroundHost( chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE); #endif - host->CreateRenderViewSoon(NULL); // create a RenderViewHost with no view + host->CreateRenderViewSoon(); OnExtensionHostCreated(host, true); } diff --git a/chrome/browser/extensions/extension_webkit_preferences.cc b/chrome/browser/extensions/extension_webkit_preferences.cc index 4be4be7..c598992 100644 --- a/chrome/browser/extensions/extension_webkit_preferences.cc +++ b/chrome/browser/extensions/extension_webkit_preferences.cc @@ -2,13 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "webkit/glue/webpreferences.h" +#include "chrome/browser/extensions/extension_webkit_preferences.h" #include "chrome/common/extensions/extension.h" +#include "webkit/glue/webpreferences.h" namespace extension_webkit_preferences { -void SetPreferences(WebPreferences* webkit_prefs, const Extension* extension) { +void SetPreferences(const Extension* extension, + content::ViewType render_view_type, + WebPreferences* webkit_prefs) { if (extension && !extension->is_hosted_app()) { // Extensions are trusted so we override any user preferences for disabling // javascript or images. @@ -21,6 +24,14 @@ void SetPreferences(WebPreferences* webkit_prefs, const Extension* extension) { // Enable privileged WebGL extensions. webkit_prefs->privileged_webgl_extensions_enabled = true; + + // Disable anything that requires the GPU process for background pages. + // See http://crbug.com/64512 and http://crbug.com/64841. + if (render_view_type == chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { + webkit_prefs->experimental_webgl_enabled = false; + webkit_prefs->accelerated_compositing_enabled = false; + webkit_prefs->accelerated_2d_canvas_enabled = false; + } } } diff --git a/chrome/browser/extensions/extension_webkit_preferences.h b/chrome/browser/extensions/extension_webkit_preferences.h index 508e8a8..e035294 100644 --- a/chrome/browser/extensions/extension_webkit_preferences.h +++ b/chrome/browser/extensions/extension_webkit_preferences.h @@ -5,12 +5,16 @@ #ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_WEBKIT_PREFERENCES_H_ #define CHROME_BROWSER_EXTENSIONS_EXTENSION_WEBKIT_PREFERENCES_H_ +#include "chrome/common/chrome_view_types.h" + class Extension; struct WebPreferences; namespace extension_webkit_preferences { -void SetPreferences(WebPreferences* preferences, const Extension* extension); +void SetPreferences(const Extension* extension, + content::ViewType render_view_type, + WebPreferences* webkit_prefs); } // namespace extension_webkit_preferences diff --git a/chrome/browser/extensions/extension_webnavigation_api.cc b/chrome/browser/extensions/extension_webnavigation_api.cc index 0cc2d01..5e54ef2 100644 --- a/chrome/browser/extensions/extension_webnavigation_api.cc +++ b/chrome/browser/extensions/extension_webnavigation_api.cc @@ -404,7 +404,8 @@ void ExtensionWebNavigationEventRouter::Retargeting( ExtensionWebNavigationTabObserver* tab_observer = ExtensionWebNavigationTabObserver::Get(details->source_tab_contents); if (!tab_observer) { - NOTREACHED(); + CHECK(details->source_tab_contents->GetRenderViewType() != + content::VIEW_TYPE_TAB_CONTENTS); return; } const FrameNavigationState& frame_navigation_state = |