diff options
Diffstat (limited to 'chrome/browser/ui/extensions')
-rw-r--r-- | chrome/browser/ui/extensions/shell_window.cc | 166 | ||||
-rw-r--r-- | chrome/browser/ui/extensions/shell_window.h | 76 |
2 files changed, 75 insertions, 167 deletions
diff --git a/chrome/browser/ui/extensions/shell_window.cc b/chrome/browser/ui/extensions/shell_window.cc index bdc53b2..bd1e950 100644 --- a/chrome/browser/ui/extensions/shell_window.cc +++ b/chrome/browser/ui/extensions/shell_window.cc @@ -6,13 +6,13 @@ #include "base/utf_string_conversions.h" #include "base/values.h" +#include "chrome/browser/extensions/app_window_contents.h" #include "chrome/browser/extensions/extension_process_manager.h" #include "chrome/browser/extensions/extension_system.h" #include "chrome/browser/extensions/image_loader.h" #include "chrome/browser/extensions/shell_window_geometry_cache.h" #include "chrome/browser/extensions/shell_window_registry.h" #include "chrome/browser/extensions/suggest_permission_util.h" -#include "chrome/browser/extensions/tab_helper.h" #include "chrome/browser/favicon/favicon_tab_helper.h" #include "chrome/browser/file_select_helper.h" #include "chrome/browser/lifetime/application_lifetime.h" @@ -27,25 +27,20 @@ #include "chrome/browser/ui/web_contents_modal_dialog_manager.h" #include "chrome/browser/view_type_utils.h" #include "chrome/common/chrome_notification_types.h" -#include "chrome/common/extensions/api/app_window.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_constants.h" #include "chrome/common/extensions/extension_messages.h" #include "chrome/common/extensions/request_media_access_permission_helper.h" -#include "content/public/browser/browser_thread.h" #include "content/public/browser/invalidate_type.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_source.h" #include "content/public/browser/notification_types.h" -#include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/resource_dispatcher_host.h" -#include "content/public/browser/site_instance.h" #include "content/public/browser/web_contents.h" #include "content/public/common/media_stream_request.h" -#include "content/public/common/renderer_preferences.h" #include "skia/ext/image_operations.h" #include "third_party/skia/include/core/SkRegion.h" #include "ui/gfx/image/image_skia.h" @@ -54,13 +49,7 @@ #include "ash/launcher/launcher_types.h" #endif -namespace app_window = extensions::api::app_window; - -using content::BrowserThread; using content::ConsoleMessageLevel; -using content::RenderViewHost; -using content::ResourceDispatcherHost; -using content::SiteInstance; using content::WebContents; using extensions::APIPermission; using extensions::RequestMediaAccessPermissionHelper; @@ -76,14 +65,6 @@ const int kPreferredIconSize = ash::kLauncherPreferredSize; const int kPreferredIconSize = extension_misc::EXTENSION_ICON_SMALL; #endif -void SuspendRenderViewHost(RenderViewHost* rvh) { - DCHECK(rvh); - BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, - base::Bind(&ResourceDispatcherHost::BlockRequestsForRoute, - base::Unretained(ResourceDispatcherHost::Get()), - rvh->GetProcess()->GetID(), rvh->GetRoutingID())); -} - } // namespace ShellWindow::CreateParams::CreateParams() @@ -103,7 +84,7 @@ ShellWindow* ShellWindow::Create(Profile* profile, const CreateParams& params) { // This object will delete itself when the window is closed. ShellWindow* window = new ShellWindow(profile, extension); - window->Init(url, params); + window->Init(url, new AppWindowContents(window), params); extensions::ShellWindowRegistry::Get(profile)->AddShellWindow(window); return window; } @@ -112,29 +93,26 @@ ShellWindow::ShellWindow(Profile* profile, const extensions::Extension* extension) : profile_(profile), extension_(extension), - web_contents_(NULL), window_type_(WINDOW_TYPE_DEFAULT), - ALLOW_THIS_IN_INITIALIZER_LIST( - extension_function_dispatcher_(profile, this)), ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), ALLOW_THIS_IN_INITIALIZER_LIST(image_loader_ptr_factory_(this)) { } void ShellWindow::Init(const GURL& url, + ShellWindowContents* shell_window_contents, const ShellWindow::CreateParams& params) { - window_type_ = params.window_type; + // Initialize the render interface and web contents + shell_window_contents_.reset(shell_window_contents); + shell_window_contents_->Initialize(profile(), url); + WebContents* web_contents = shell_window_contents_->GetWebContents(); + WebContentsModalDialogManager::CreateForWebContents(web_contents); + FaviconTabHelper::CreateForWebContents(web_contents); - web_contents_.reset(WebContents::Create(WebContents::CreateParams( - profile(), SiteInstance::CreateForURL(profile(), url)))); - WebContentsModalDialogManager::CreateForWebContents(web_contents_.get()); - FaviconTabHelper::CreateForWebContents(web_contents_.get()); + web_contents->SetDelegate(this); + chrome::SetViewType(web_contents, chrome::VIEW_TYPE_APP_SHELL); - content::WebContentsObserver::Observe(web_contents_.get()); - web_contents_->SetDelegate(this); - chrome::SetViewType(web_contents_.get(), chrome::VIEW_TYPE_APP_SHELL); - web_contents_->GetMutableRendererPrefs()-> - browser_handles_all_top_level_requests = true; - web_contents_->GetRenderViewHost()->SyncRendererPrefs(); + // Initialize the window + window_type_ = params.window_type; gfx::Rect bounds = params.bounds; @@ -192,34 +170,7 @@ void ShellWindow::Init(const GURL& url, GetBaseWindow()->Show(); } - // If the new view is in the same process as the creator, block the created - // RVH from loading anything until the background page has had a chance to do - // any initialization it wants. If it's a different process, the new RVH - // shouldn't communicate with the background page anyway (e.g. sandboxed). - if (web_contents_->GetRenderViewHost()->GetProcess()->GetID() == - params.creator_process_id) { - SuspendRenderViewHost(web_contents_->GetRenderViewHost()); - } else { - VLOG(1) << "ShellWindow created in new process (" - << web_contents_->GetRenderViewHost()->GetProcess()->GetID() - << ") != creator (" << params.creator_process_id - << "). Routing disabled."; - } - - // TODO(jeremya): there's a bug where navigating a web contents to an - // extension URL causes it to create a new RVH and discard the old (perfectly - // usable) one. To work around this, we watch for a RVH_CHANGED message from - // the web contents (which will be sent during LoadURL) and suspend resource - // requests on the new RVH to ensure that we block the new RVH from loading - // anything. It should be okay to remove the NOTIFICATION_RVH_CHANGED - // registration once http://crbug.com/123007 is fixed. - registrar_.Add(this, content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED, - content::Source<content::NavigationController>( - &web_contents_->GetController())); - web_contents_->GetController().LoadURL( - url, content::Referrer(), content::PAGE_TRANSITION_LINK, - std::string()); - registrar_.RemoveAll(); + shell_window_contents_->LoadContents(params.creator_process_id); registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, content::Source<Profile>(profile_)); @@ -262,8 +213,6 @@ void ShellWindow::RequestMediaAccessPermission( WebContents* ShellWindow::OpenURLFromTab(WebContents* source, const content::OpenURLParams& params) { - DCHECK(source == web_contents_); - // Don't allow the current tab to be navigated. It would be nice to map all // anchor tags (even those without target="_blank") to new tabs, but right // now we can't distinguish between those and <meta> refreshes or window.href @@ -311,7 +260,6 @@ void ShellWindow::AddNewContents(WebContents* source, const gfx::Rect& initial_pos, bool user_gesture, bool* was_blocked) { - DCHECK(source == web_contents_); DCHECK(Profile::FromBrowserContext(new_contents->GetBrowserContext()) == profile_); Browser* browser = @@ -327,7 +275,6 @@ void ShellWindow::AddNewContents(WebContents* source, void ShellWindow::HandleKeyboardEvent( WebContents* source, const content::NativeWebKeyboardEvent& event) { - DCHECK_EQ(source, web_contents_); native_app_window_->HandleKeyboardEvent(event); } @@ -344,37 +291,15 @@ void ShellWindow::RequestToLockMouse(WebContents* web_contents, void ShellWindow::OnNativeClose() { extensions::ShellWindowRegistry::Get(profile_)->RemoveShellWindow(this); - content::RenderViewHost* rvh = web_contents_->GetRenderViewHost(); - rvh->Send(new ExtensionMsg_AppWindowClosed(rvh->GetRoutingID())); + if (shell_window_contents_) + shell_window_contents_->NativeWindowClosed(); delete this; } void ShellWindow::OnNativeWindowChanged() { SaveWindowPosition(); - if (!native_app_window_ || !web_contents_) - return; - ListValue args; - DictionaryValue* dictionary = new DictionaryValue(); - args.Append(dictionary); - - gfx::Rect bounds = native_app_window_->GetBounds(); - bounds.Inset(native_app_window_->GetFrameInsets()); - app_window::Bounds update; - update.left.reset(new int(bounds.x())); - update.top.reset(new int(bounds.y())); - update.width.reset(new int(bounds.width())); - update.height.reset(new int(bounds.height())); - dictionary->Set("bounds", update.ToValue().release()); - dictionary->SetBoolean("minimized", native_app_window_->IsMinimized()); - dictionary->SetBoolean("maximized", native_app_window_->IsMaximized()); - - content::RenderViewHost* rvh = web_contents_->GetRenderViewHost(); - rvh->Send(new ExtensionMsg_MessageInvoke(rvh->GetRoutingID(), - extension_->id(), - "updateAppWindowProperties", - args, - GURL(), - false)); + if (shell_window_contents_ && native_app_window_) + shell_window_contents_->NativeWindowChanged(native_app_window_.get()); } gfx::Image* ShellWindow::GetAppListIcon() { @@ -392,6 +317,10 @@ gfx::Image* ShellWindow::GetAppListIcon() { return new gfx::Image(gfx::ImageSkia::CreateFrom1xBitmap(bmp)); } +content::WebContents* ShellWindow::web_contents() const { + return shell_window_contents_->GetWebContents(); +} + NativeAppWindow* ShellWindow::GetBaseWindow() { return native_app_window_.get(); } @@ -420,25 +349,14 @@ void ShellWindow::SetAppIconUrl(const GURL& url) { weak_ptr_factory_.GetWeakPtr())); } -//------------------------------------------------------------------------------ -// Private methods - -bool ShellWindow::OnMessageReceived(const IPC::Message& message) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(ShellWindow, message) - IPC_MESSAGE_HANDLER(ExtensionHostMsg_Request, OnRequest) - IPC_MESSAGE_HANDLER(ExtensionHostMsg_UpdateDraggableRegions, - UpdateDraggableRegions) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; -} - void ShellWindow::UpdateDraggableRegions( const std::vector<extensions::DraggableRegion>& regions) { native_app_window_->UpdateDraggableRegions(regions); } +//------------------------------------------------------------------------------ +// Private methods + void ShellWindow::OnImageLoaded(const gfx::Image& image) { UpdateAppIcon(image); } @@ -486,7 +404,6 @@ void ShellWindow::UpdateExtensionAppIcon() { } void ShellWindow::CloseContents(WebContents* contents) { - DCHECK(contents == web_contents_); native_app_window_->Close(); } @@ -500,18 +417,15 @@ void ShellWindow::RunFileChooser(WebContents* tab, } bool ShellWindow::IsPopupOrPanel(const WebContents* source) const { - DCHECK(source == web_contents_.get()); return true; } void ShellWindow::MoveContents(WebContents* source, const gfx::Rect& pos) { - DCHECK(source == web_contents_.get()); native_app_window_->SetBounds(pos); } void ShellWindow::NavigationStateChanged( const content::WebContents* source, unsigned changed_flags) { - DCHECK(source == web_contents_.get()); if (changed_flags & content::INVALIDATE_TYPE_TITLE) native_app_window_->UpdateWindowTitle(); else if (changed_flags & content::INVALIDATE_TYPE_TAB) @@ -520,14 +434,10 @@ void ShellWindow::NavigationStateChanged( void ShellWindow::ToggleFullscreenModeForTab(content::WebContents* source, bool enter_fullscreen) { - DCHECK(source == web_contents_.get()); - if (source != web_contents_.get()) - return; - bool has_permission = IsExtensionWithPermissionOrSuggestInConsole( APIPermission::kFullscreen, extension_, - web_contents_->GetRenderViewHost()); + source->GetRenderViewHost()); if (has_permission) native_app_window_->SetFullscreen(enter_fullscreen); @@ -535,7 +445,6 @@ void ShellWindow::ToggleFullscreenModeForTab(content::WebContents* source, bool ShellWindow::IsFullscreenForTabOrPending( const content::WebContents* source) const { - DCHECK(source == web_contents_.get()); return native_app_window_->IsFullscreenOrPending(); } @@ -544,13 +453,6 @@ void ShellWindow::Observe(int type, const content::NotificationDetails& details) { switch (type) { case content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED: { - // TODO(jeremya): once http://crbug.com/123007 is fixed, we'll no longer - // need to suspend resource requests here (the call in the constructor - // should be enough). - content::Details<std::pair<RenderViewHost*, RenderViewHost*> > - host_details(details); - if (host_details->first) - SuspendRenderViewHost(host_details->second); // TODO(jianli): once http://crbug.com/123007 is fixed, we'll no longer // need to make the native window (ShellWindowViews specially) update // the clickthrough region for the new RVH. @@ -573,29 +475,15 @@ void ShellWindow::Observe(int type, } } -extensions::WindowController* -ShellWindow::GetExtensionWindowController() const { - return NULL; -} - -content::WebContents* ShellWindow::GetAssociatedWebContents() const { - return web_contents_.get(); -} - extensions::ActiveTabPermissionGranter* ShellWindow::GetActiveTabPermissionGranter() { // Shell windows don't support the activeTab permission. return NULL; } -void ShellWindow::OnRequest(const ExtensionHostMsg_Request_Params& params) { - extension_function_dispatcher_.Dispatch(params, - web_contents_->GetRenderViewHost()); -} - void ShellWindow::AddMessageToDevToolsConsole(ConsoleMessageLevel level, const std::string& message) { - content::RenderViewHost* rvh = web_contents_->GetRenderViewHost(); + content::RenderViewHost* rvh = web_contents()->GetRenderViewHost(); rvh->Send(new ExtensionMsg_AddMessageToConsole( rvh->GetRoutingID(), level, message)); } diff --git a/chrome/browser/ui/extensions/shell_window.h b/chrome/browser/ui/extensions/shell_window.h index 981c725..4d66ae0 100644 --- a/chrome/browser/ui/extensions/shell_window.h +++ b/chrome/browser/ui/extensions/shell_window.h @@ -6,14 +6,13 @@ #define CHROME_BROWSER_UI_EXTENSIONS_SHELL_WINDOW_H_ #include "base/memory/scoped_ptr.h" -#include "chrome/browser/extensions/extension_function_dispatcher.h" +#include "base/memory/weak_ptr.h" #include "chrome/browser/extensions/extension_keybinding_registry.h" #include "chrome/browser/sessions/session_id.h" #include "chrome/browser/ui/base_window.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" #include "content/public/browser/web_contents_delegate.h" -#include "content/public/browser/web_contents_observer.h" #include "content/public/common/console_message_level.h" #include "ui/gfx/image/image.h" #include "ui/gfx/rect.h" @@ -34,12 +33,37 @@ class WindowController; struct DraggableRegion; } +// Manages the web contents for Shell Windows. The implementation for this +// class should create and maintain the WebContents for the window, and handle +// any message passing between the web contents and the extension system or +// native window. +class ShellWindowContents { + public: + ShellWindowContents() {} + virtual ~ShellWindowContents() {} + + // Called to initialize the WebContents, before the app window is created. + virtual void Initialize(Profile* profile, const GURL& url) = 0; + + // Called to load the contents, after the app window is created. + virtual void LoadContents(int32 creator_process_id) = 0; + + // Called when the native window changes. + virtual void NativeWindowChanged(NativeAppWindow* native_app_window) = 0; + + // Called when the native window closes. + virtual void NativeWindowClosed() = 0; + + virtual content::WebContents* GetWebContents() const = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(ShellWindowContents); +}; + // ShellWindow is the type of window used by platform apps. Shell windows // have a WebContents but none of the chrome of normal browser windows. class ShellWindow : public content::NotificationObserver, public content::WebContentsDelegate, - public content::WebContentsObserver, - public ExtensionFunctionDispatcher::Delegate, public extensions::ExtensionKeybindingRegistry::Delegate { public: enum WindowType { @@ -78,6 +102,7 @@ class ShellWindow : public content::NotificationObserver, bool hidden; }; + // Helper function for creating and intiailizing a v2 app window. static ShellWindow* Create(Profile* profile, const extensions::Extension* extension, const GURL& url, @@ -88,10 +113,22 @@ class ShellWindow : public content::NotificationObserver, static SkRegion* RawDraggableRegionsToSkRegion( const std::vector<extensions::DraggableRegion>& regions); + // The constructor and Init methods are public for constructing a ShellWindow + // with a non-standard render interface (e.g. v1 apps using Ash Panels). + // Normally ShellWindow::Create should be used. + ShellWindow(Profile* profile, const extensions::Extension* extension); + + // Initializes the render interface, web contents, and native window. + // |shell_window_contents| will become owned by ShellWindow. + void Init(const GURL& url, + ShellWindowContents* shell_window_contents, + const CreateParams& params); + + const std::string& window_key() const { return window_key_; } const SessionID& session_id() const { return session_id_; } const extensions::Extension* extension() const { return extension_; } - content::WebContents* web_contents() const { return web_contents_.get(); } + content::WebContents* web_contents() const; WindowType window_type() const { return window_type_; } Profile* profile() const { return profile_; } const gfx::Image& app_icon() const { return app_icon_; } @@ -107,7 +144,7 @@ class ShellWindow : public content::NotificationObserver, // NativeAppWindows should call this to determine what the window's title // is on startup and from within UpdateWindowTitle(). - virtual string16 GetTitle() const; + string16 GetTitle() const; // Call to notify ShellRegistry and delete the window. Subclasses should // invoke this method instead of using "delete this". @@ -120,22 +157,17 @@ class ShellWindow : public content::NotificationObserver, // Specifies a url for the launcher icon. void SetAppIconUrl(const GURL& icon_url); + // Called from the render interface to modify the draggable regions. + void UpdateDraggableRegions( + const std::vector<extensions::DraggableRegion>& regions); + protected: - ShellWindow(Profile* profile, - const extensions::Extension* extension); virtual ~ShellWindow(); private: // PlatformAppBrowserTest needs access to web_contents() friend class extensions::PlatformAppBrowserTest; - // Instantiates a platform-specific ShellWindow subclass (one implementation - // per platform). Public users of ShellWindow should use ShellWindow::Create. - void Init(const GURL& url, const CreateParams& params); - - // content::WebContentsObserver implementation. - virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; - // content::WebContentsDelegate implementation. virtual void CloseContents(content::WebContents* contents) OVERRIDE; virtual bool ShouldSuppressDialogs() OVERRIDE; @@ -177,14 +209,6 @@ class ShellWindow : public content::NotificationObserver, const content::NotificationSource& source, const content::NotificationDetails& details) OVERRIDE; - // ExtensionFunctionDispatcher::Delegate implementation. - virtual extensions::WindowController* GetExtensionWindowController() const - OVERRIDE; - virtual content::WebContents* GetAssociatedWebContents() const OVERRIDE; - - // Message handlers. - void OnRequest(const ExtensionHostMsg_Request_Params& params); - // Helper method to add a message to the renderer's DevTools console. void AddMessageToDevToolsConsole(content::ConsoleMessageLevel level, const std::string& message); @@ -192,9 +216,6 @@ class ShellWindow : public content::NotificationObserver, // Saves the window geometry/position. void SaveWindowPosition(); - virtual void UpdateDraggableRegions( - const std::vector<extensions::DraggableRegion>& regions); - // Load the app's image, firing a load state change when loaded. void UpdateExtensionAppIcon(); @@ -222,10 +243,8 @@ class ShellWindow : public content::NotificationObserver, std::string window_key_; const SessionID session_id_; - scoped_ptr<content::WebContents> web_contents_; WindowType window_type_; content::NotificationRegistrar registrar_; - ExtensionFunctionDispatcher extension_function_dispatcher_; // Icon shown in the task bar. gfx::Image app_icon_; @@ -235,6 +254,7 @@ class ShellWindow : public content::NotificationObserver, GURL app_icon_url_; scoped_ptr<NativeAppWindow> native_app_window_; + scoped_ptr<ShellWindowContents> shell_window_contents_; base::WeakPtrFactory<ShellWindow> weak_ptr_factory_; |