summaryrefslogtreecommitdiffstats
path: root/chrome/browser/ui/extensions
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/ui/extensions')
-rw-r--r--chrome/browser/ui/extensions/shell_window.cc166
-rw-r--r--chrome/browser/ui/extensions/shell_window.h76
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_;