diff options
Diffstat (limited to 'chrome/browser/ui/extensions')
-rw-r--r-- | chrome/browser/ui/extensions/shell_window.cc | 134 | ||||
-rw-r--r-- | chrome/browser/ui/extensions/shell_window.h | 68 |
2 files changed, 136 insertions, 66 deletions
diff --git a/chrome/browser/ui/extensions/shell_window.cc b/chrome/browser/ui/extensions/shell_window.cc index f624f95..0371ab7 100644 --- a/chrome/browser/ui/extensions/shell_window.cc +++ b/chrome/browser/ui/extensions/shell_window.cc @@ -8,14 +8,24 @@ #include "chrome/browser/extensions/extension_process_manager.h" #include "chrome/browser/extensions/extension_tabs_module_constants.h" #include "chrome/browser/extensions/extension_window_controller.h" +#include "chrome/browser/extensions/shell_window_registry.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sessions/session_id.h" #include "chrome/common/chrome_notification_types.h" +#include "chrome/common/chrome_view_type.h" #include "chrome/common/extensions/extension.h" +#include "chrome/common/extensions/extension_messages.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_view_host.h" +#include "content/public/browser/site_instance.h" +#include "content/public/browser/web_contents.h" +#include "content/public/common/renderer_preferences.h" + +using content::SiteInstance; +using content::WebContents; namespace internal { @@ -26,7 +36,6 @@ class ShellWindowController : public ExtensionWindowController { // Overriden from ExtensionWindowController virtual int GetWindowId() const OVERRIDE; virtual std::string GetWindowTypeText() const OVERRIDE; - virtual base::DictionaryValue* CreateWindowValue() const OVERRIDE; virtual base::DictionaryValue* CreateWindowValueWithTabs() const OVERRIDE; virtual bool CanClose(Reason* reason) const OVERRIDE; virtual void SetFullscreenMode(bool is_fullscreen, @@ -49,15 +58,8 @@ int ShellWindowController::GetWindowId() const { return static_cast<int>(shell_window_->session_id().id()); } -namespace keys = extension_tabs_module_constants; - std::string ShellWindowController::GetWindowTypeText() const { - return keys::kWindowTypeValueShell; -} - -base::DictionaryValue* ShellWindowController::CreateWindowValue() const { - DictionaryValue* result = ExtensionWindowController::CreateWindowValue(); - return result; + return extension_tabs_module_constants::kWindowTypeValueShell; } base::DictionaryValue* ShellWindowController::CreateWindowValueWithTabs() @@ -79,48 +81,32 @@ void ShellWindowController::SetFullscreenMode(bool is_fullscreen, ShellWindow* ShellWindow::Create(Profile* profile, const Extension* extension, const GURL& url) { - ExtensionProcessManager* manager = profile->GetExtensionProcessManager(); - DCHECK(manager); - // This object will delete itself when the window is closed. - return ShellWindow::CreateShellWindow( - manager->CreateShellHost(extension, url)); -} - -void ShellWindow::Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - switch (type) { - case chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE: - if (content::Details<ExtensionHost>(host_.get()) == details) - Close(); - break; - case chrome::NOTIFICATION_EXTENSION_UNLOADED: { - const Extension* unloaded_extension = - content::Details<UnloadedExtensionInfo>(details)->extension; - // We compare extension IDs and not Extension pointers since ExtensionHost - // nulls out its Extension pointer when it gets this notification. - if (host_->extension_id() == unloaded_extension->id()) - Close(); - break; - } - case content::NOTIFICATION_APP_TERMINATING: - Close(); - break; - default: - NOTREACHED() << "Received unexpected notification"; - } + return ShellWindow::CreateImpl(profile, extension, url); } -ShellWindow::ShellWindow(ExtensionHost* host) - : host_(host) { - // Close the window in response to window.close() and the like. - registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE, - content::Source<Profile>(host->profile())); - // Also close if the window if the extension has been unloaded (parallels - // NOTIFICATION_EXTENSION_UNLOADED closing the app's tabs in TabStripModel). +ShellWindow::ShellWindow(Profile* profile, + const Extension* extension, + const GURL& url) + : profile_(profile), + extension_(extension), + ALLOW_THIS_IN_INITIALIZER_LIST( + extension_function_dispatcher_(profile, this)) { + web_contents_.reset(WebContents::Create( + profile, SiteInstance::CreateForURL(profile, url), MSG_ROUTING_NONE, NULL, + NULL)); + content::WebContentsObserver::Observe(web_contents_.get()); + web_contents_->SetDelegate(this); + web_contents_->SetViewType(chrome::VIEW_TYPE_APP_SHELL); + web_contents_->GetMutableRendererPrefs()->browser_handles_all_requests = + true; + web_contents_->GetRenderViewHost()->SyncRendererPrefs(); + + web_contents_->GetController().LoadURL( + url, content::Referrer(), content::PAGE_TRANSITION_LINK, + std::string()); registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, - content::Source<Profile>(host->profile())); + content::Source<Profile>(profile_)); // Close when the browser is exiting. // TODO(mihaip): we probably don't want this in the long run (when platform // apps are no longer tied to the browser process). @@ -132,7 +118,9 @@ ShellWindow::ShellWindow(ExtensionHost* host) // Make this window available to the extension API. extension_window_controller_.reset( - new internal::ShellWindowController(this, host->profile())); + new internal::ShellWindowController(this, profile_)); + + ShellWindowRegistry::Get(profile_)->AddShellWindow(this); } ShellWindow::~ShellWindow() { @@ -140,6 +128,56 @@ ShellWindow::~ShellWindow() { // last window open. registrar_.RemoveAll(); + ShellWindowRegistry::Get(profile_)->RemoveShellWindow(this); + // Remove shutdown prevention. BrowserList::EndKeepAlive(); } + +bool ShellWindow::OnMessageReceived(const IPC::Message& message) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(ShellWindow, message) + IPC_MESSAGE_HANDLER(ExtensionHostMsg_Request, OnRequest) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +void ShellWindow::CloseContents(WebContents* contents) { + Close(); +} + +// TODO(benwells): Rearrange so users of this can call +// WebContents::set_should_suppress_dialogs(bool) instead of overriding +// this delegate function. +bool ShellWindow::ShouldSuppressDialogs() { + return true; +} + +void ShellWindow::Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) { + switch (type) { + case chrome::NOTIFICATION_EXTENSION_UNLOADED: { + const Extension* unloaded_extension = + content::Details<UnloadedExtensionInfo>(details)->extension; + if (extension_ == unloaded_extension) + Close(); + break; + } + case content::NOTIFICATION_APP_TERMINATING: + Close(); + break; + default: + NOTREACHED() << "Received unexpected notification"; + } +} + +ExtensionWindowController* ShellWindow::GetExtensionWindowController() const { + return extension_window_controller_.get(); +} + +void ShellWindow::OnRequest(const ExtensionHostMsg_Request_Params& params) { + extension_function_dispatcher_.Dispatch(params, + web_contents_->GetRenderViewHost()); +} diff --git a/chrome/browser/ui/extensions/shell_window.h b/chrome/browser/ui/extensions/shell_window.h index 2790b74..dec4dd8 100644 --- a/chrome/browser/ui/extensions/shell_window.h +++ b/chrome/browser/ui/extensions/shell_window.h @@ -7,14 +7,15 @@ #pragma once #include "base/memory/scoped_ptr.h" +#include "chrome/browser/extensions/extension_function_dispatcher.h" #include "chrome/browser/sessions/session_id.h" -#include "chrome/browser/extensions/extension_host.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" class Extension; -class ExtensionHost; class ExtensionWindowController; class GURL; class Profile; @@ -23,43 +24,74 @@ namespace content { class WebContents; } +// 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 BaseWindow { public: - // TODO(mihaip): Switch from hardcoded defaults to passing in the window - // creation parameters to ShellWindow::Create. - static const int kDefaultWidth = 512; - static const int kDefaultHeight = 384; + static ShellWindow* Create(Profile* profile, + const Extension* extension, + const GURL& url); - content::WebContents* web_contents() const { return host_->host_contents(); } const SessionID& session_id() const { return session_id_; } const ExtensionWindowController* extension_window_controller() const { return extension_window_controller_.get(); } - static ShellWindow* Create(Profile* profile, - const Extension* extension, - const GURL& url); + protected: + // TODO(mihaip): Switch from hardcoded defaults to passing in the window + // creation parameters to ShellWindow::Create. + static const int kDefaultWidth = 512; + static const int kDefaultHeight = 384; + + ShellWindow(Profile* profile, + const Extension* extension, + const GURL& url); + virtual ~ShellWindow(); + + const Extension* extension() const { return extension_; } + content::WebContents* web_contents() const { return web_contents_.get(); } + + private: + // PlatformAppBrowserTest needs access to web_contents() + friend class PlatformAppBrowserTest; + + // Instantiates a platform-specific ShellWindow subclass (one implementation + // per platform). Public users of ShellWindow should use ShellWindow::Create. + static ShellWindow* CreateImpl(Profile* profile, + const Extension* extension, + const GURL& url); + + // content::WebContentsObserver + virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; + + // content::WebContentsDelegate + virtual void CloseContents(content::WebContents* contents) OVERRIDE; + virtual bool ShouldSuppressDialogs() OVERRIDE; // content::NotificationObserver implementation. virtual void Observe(int type, const content::NotificationSource& source, const content::NotificationDetails& details) OVERRIDE; - protected: - explicit ShellWindow(ExtensionHost* host_); - virtual ~ShellWindow(); + virtual ExtensionWindowController* GetExtensionWindowController() const + OVERRIDE; - // Instantiates a platform-specific ShellWindow subclass (one implementation - // per platform). Public users of ShellWindow should use ShellWindow::Create. - static ShellWindow* CreateShellWindow(ExtensionHost* host); + // Message handlers. + void OnRequest(const ExtensionHostMsg_Request_Params& params); + + Profile* profile_; // weak pointer - owned by ProfileManager. + const Extension* extension_; // weak pointer - owned by ExtensionService. const SessionID session_id_; - scoped_ptr<ExtensionHost> host_; + scoped_ptr<content::WebContents> web_contents_; content::NotificationRegistrar registrar_; scoped_ptr<ExtensionWindowController> extension_window_controller_; + ExtensionFunctionDispatcher extension_function_dispatcher_; - private: DISALLOW_COPY_AND_ASSIGN(ShellWindow); }; |