summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authormpcomplete@google.com <mpcomplete@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-29 22:24:31 +0000
committermpcomplete@google.com <mpcomplete@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-29 22:24:31 +0000
commitc64631651a4267994dbdd336243e06b64e4e7a5f (patch)
tree23700eae496a6cf3cda0beea3742f12656c8cd4b /chrome
parent45671618a6690a8501f01905a4ed6d19cfcdc0b1 (diff)
downloadchromium_src-c64631651a4267994dbdd336243e06b64e4e7a5f.zip
chromium_src-c64631651a4267994dbdd336243e06b64e4e7a5f.tar.gz
chromium_src-c64631651a4267994dbdd336243e06b64e4e7a5f.tar.bz2
Refactor ExtensionView to support a UI-less extension instance.
- Introduce ExtensionHost, which is the guy that talks to the RenderViewHost. - ExtensionView holds an ExtensionHost, and also renders its contents in an HWND. - Added code to load a page optionally specified in the manifest as a background process whenever it exists. Review URL: http://codereview.chromium.org/92043 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@14902 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/browser.vcproj8
-rw-r--r--chrome/browser/browser_list.cc17
-rw-r--r--chrome/browser/browser_list.h5
-rw-r--r--chrome/browser/extensions/extension.cc13
-rw-r--r--chrome/browser/extensions/extension.h8
-rwxr-xr-xchrome/browser/extensions/extension_host.cc171
-rwxr-xr-xchrome/browser/extensions/extension_host.h100
-rwxr-xr-xchrome/browser/extensions/extension_view.cc212
-rwxr-xr-xchrome/browser/extensions/extension_view.h113
-rwxr-xr-xchrome/browser/extensions/extension_view_unittest.cc22
-rw-r--r--chrome/browser/extensions/extensions_service.cc26
-rw-r--r--chrome/browser/extensions/extensions_service.h10
-rw-r--r--chrome/browser/extensions/extensions_service_unittest.cc3
-rw-r--r--chrome/browser/renderer_host/render_view_host.cc4
-rw-r--r--chrome/browser/renderer_host/render_widget_host.cc14
-rw-r--r--chrome/browser/renderer_host/render_widget_host.h4
-rw-r--r--chrome/chrome.gyp2
-rw-r--r--chrome/common/temp_scaffolding_stubs.h31
-rw-r--r--chrome/test/data/extensions/good/extension2/2/background.html1
-rw-r--r--chrome/test/data/extensions/good/extension2/2/manifest.json3
20 files changed, 529 insertions, 238 deletions
diff --git a/chrome/browser/browser.vcproj b/chrome/browser/browser.vcproj
index 96114e4..88150e2 100644
--- a/chrome/browser/browser.vcproj
+++ b/chrome/browser/browser.vcproj
@@ -1958,6 +1958,14 @@
>
</File>
<File
+ RelativePath=".\extensions\extension_host.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\extensions\extension_host.h"
+ >
+ </File>
+ <File
RelativePath=".\extensions\extension_message_service.cc"
>
</File>
diff --git a/chrome/browser/browser_list.cc b/chrome/browser/browser_list.cc
index ca2963f..c1676c0 100644
--- a/chrome/browser/browser_list.cc
+++ b/chrome/browser/browser_list.cc
@@ -223,6 +223,23 @@ Browser* BrowserList::FindBrowserWithType(Profile* p, Browser::Type t) {
}
// static
+Browser* BrowserList::FindBrowserWithProfile(Profile* p) {
+ Browser* last_active = GetLastActive();
+ if (last_active && last_active->profile() == p)
+ return last_active;
+
+ BrowserList::const_iterator i;
+ for (i = BrowserList::begin(); i != BrowserList::end(); ++i) {
+ if (*i == last_active)
+ continue;
+
+ if ((*i)->profile() == p)
+ return *i;
+ }
+ return NULL;
+}
+
+// static
Browser* BrowserList::FindBrowserWithID(SessionID::id_type desired_id) {
BrowserList::const_iterator i;
for (i = BrowserList::begin(); i != BrowserList::end(); ++i) {
diff --git a/chrome/browser/browser_list.h b/chrome/browser/browser_list.h
index 2488a09..faa2f64 100644
--- a/chrome/browser/browser_list.h
+++ b/chrome/browser/browser_list.h
@@ -59,6 +59,11 @@ class BrowserList {
// is returned. Returns NULL if no such browser currently exists.
static Browser* FindBrowserWithType(Profile* p, Browser::Type t);
+ // Find an existing browser window with the provided profile. If the last
+ // active has the right profile, it is returned. Returns NULL if no such
+ // browser currently exists.
+ static Browser* FindBrowserWithProfile(Profile* p);
+
// Find an existing browser with the provided ID. Returns NULL if no such
// browser currently exists.
static Browser* FindBrowserWithID(SessionID::id_type desired_id);
diff --git a/chrome/browser/extensions/extension.cc b/chrome/browser/extensions/extension.cc
index 1aeaeaa..6b2bb3e 100644
--- a/chrome/browser/extensions/extension.cc
+++ b/chrome/browser/extensions/extension.cc
@@ -24,6 +24,7 @@ const wchar_t* Extension::kMatchesKey = L"matches";
const wchar_t* Extension::kNameKey = L"name";
const wchar_t* Extension::kPermissionsKey = L"permissions";
const wchar_t* Extension::kPluginsDirKey = L"plugins_dir";
+const wchar_t* Extension::kBackgroundKey = L"background";
const wchar_t* Extension::kRunAtKey = L"run_at";
const wchar_t* Extension::kThemeKey = L"theme";
const wchar_t* Extension::kToolstripsKey = L"toolstrips";
@@ -75,6 +76,8 @@ const char* Extension::kInvalidPermissionSchemeError =
"allowed.";
const char* Extension::kInvalidPluginsDirError =
"Invalid value for 'plugins_dir'.";
+const char* Extension::kInvalidBackgroundError =
+ "Invalid value for 'background'.";
const char* Extension::kInvalidRunAtError =
"Invalid value for 'content_scripts[*].run_at'.";
const char* Extension::kInvalidToolstripError =
@@ -403,6 +406,16 @@ bool Extension::InitFromValue(const DictionaryValue& source, bool require_id,
plugins_dir_ = path_.AppendASCII(plugins_dir);
}
+ // Initialize background url (optional).
+ if (source.HasKey(kBackgroundKey)) {
+ std::string background_str;
+ if (!source.GetString(kBackgroundKey, &background_str)) {
+ *error = kInvalidBackgroundError;
+ return false;
+ }
+ background_url_ = GetResourceURL(background_str);
+ }
+
// Initialize toolstrips (optional).
if (source.HasKey(kToolstripsKey)) {
ListValue* list_value;
diff --git a/chrome/browser/extensions/extension.h b/chrome/browser/extensions/extension.h
index 2f59115..95f04bb 100644
--- a/chrome/browser/extensions/extension.h
+++ b/chrome/browser/extensions/extension.h
@@ -38,6 +38,7 @@ class Extension {
static const wchar_t* kNameKey;
static const wchar_t* kPermissionsKey;
static const wchar_t* kPluginsDirKey;
+ static const wchar_t* kBackgroundKey;
static const wchar_t* kRunAtKey;
static const wchar_t* kThemeKey;
static const wchar_t* kToolstripsKey;
@@ -63,6 +64,7 @@ class Extension {
static const char* kInvalidMatchesError;
static const char* kInvalidNameError;
static const char* kInvalidPluginsDirError;
+ static const char* kInvalidBackgroundError;
static const char* kInvalidRunAtError;
static const char* kInvalidToolstripError;
static const char* kInvalidToolstripsError;
@@ -122,6 +124,7 @@ class Extension {
const std::string& description() const { return description_; }
const UserScriptList& content_scripts() const { return content_scripts_; }
const FilePath& plugins_dir() const { return plugins_dir_; }
+ const GURL& background_url() const { return background_url_; }
const std::vector<std::string>& toolstrips() const { return toolstrips_; }
const std::vector<URLPattern>& permissions() const {
return permissions_; }
@@ -163,6 +166,10 @@ class Extension {
// contains.
FilePath plugins_dir_;
+ // Optional URL to a master page of which a single instance should be always
+ // loaded in the background.
+ GURL background_url_;
+
// Paths to HTML files to be displayed in the toolbar.
std::vector<std::string> toolstrips_;
@@ -174,6 +181,7 @@ class Extension {
// A map of resource id's to relative file paths.
std::map<const std::wstring, std::string> theme_paths_;
+ // The sites this extension has permission to talk to (using XHR, etc).
std::vector<URLPattern> permissions_;
// We implement copy, but not assign.
diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc
new file mode 100755
index 0000000..16d55e8
--- /dev/null
+++ b/chrome/browser/extensions/extension_host.cc
@@ -0,0 +1,171 @@
+// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/extensions/extension_host.h"
+
+#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_list.h"
+#include "chrome/browser/extensions/extension.h"
+#include "chrome/browser/extensions/extension_message_service.h"
+#include "chrome/browser/extensions/extension_view.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/renderer_host/render_view_host.h"
+#include "chrome/browser/renderer_host/render_process_host.h"
+#include "chrome/browser/renderer_host/render_widget_host.h"
+#include "chrome/browser/renderer_host/render_widget_host_view.h"
+#include "chrome/browser/tab_contents/site_instance.h"
+#include "chrome/browser/tab_contents/web_contents.h"
+#include "chrome/browser/tab_contents/tab_contents_view.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/common/pref_service.h"
+#include "chrome/common/resource_bundle.h"
+
+#include "grit/browser_resources.h"
+#include "grit/generated_resources.h"
+
+#include "webkit/glue/context_menu.h"
+
+ExtensionHost::ExtensionHost(Extension* extension, SiteInstance* site_instance)
+ : extension_(extension), view_(NULL), did_stop_loading_(false) {
+ render_view_host_ = new RenderViewHost(
+ site_instance, this, MSG_ROUTING_NONE, NULL);
+ render_view_host_->AllowExtensionBindings();
+}
+
+ExtensionHost::~ExtensionHost() {
+ render_view_host_->Shutdown(); // deletes render_view_host
+}
+
+SiteInstance* ExtensionHost::site_instance() const {
+ return render_view_host_->site_instance();
+}
+
+void ExtensionHost::CreateRenderView(const GURL& url,
+ RenderWidgetHostView* host_view) {
+ render_view_host_->set_view(host_view);
+ render_view_host_->CreateRenderView();
+ render_view_host_->NavigateToURL(url);
+}
+
+void ExtensionHost::DidContentsPreferredWidthChange(const int pref_width) {
+ if (view_)
+ view_->DidContentsPreferredWidthChange(pref_width);
+}
+
+void ExtensionHost::RenderViewCreated(RenderViewHost* rvh) {
+ URLRequestContext* context = rvh->process()->profile()->GetRequestContext();
+ ExtensionMessageService::GetInstance(context)->RegisterExtension(
+ extension_->id(), rvh->process()->pid());
+}
+
+WebPreferences ExtensionHost::GetWebkitPrefs() {
+ PrefService* prefs = render_view_host()->process()->profile()->GetPrefs();
+ const bool kIsDomUI = true;
+ return RenderViewHostDelegateHelper::GetWebkitPrefs(prefs, kIsDomUI);
+}
+
+void ExtensionHost::RunJavaScriptMessage(
+ const std::wstring& message,
+ const std::wstring& default_prompt,
+ const GURL& frame_url,
+ const int flags,
+ IPC::Message* reply_msg,
+ bool* did_suppress_message) {
+ // Automatically cancel the javascript alert (otherwise the renderer hangs
+ // indefinitely).
+ *did_suppress_message = true;
+ render_view_host()->JavaScriptMessageBoxClosed(reply_msg, true, L"");
+}
+
+void ExtensionHost::DidStartLoading(RenderViewHost* render_view_host) {
+ static const StringPiece toolstrip_css(
+ ResourceBundle::GetSharedInstance().GetRawDataResource(
+ IDR_EXTENSIONS_TOOLSTRIP_CSS));
+ render_view_host->InsertCSSInWebFrame(L"", toolstrip_css.as_string());
+}
+
+void ExtensionHost::DidStopLoading(RenderViewHost* render_view_host) {
+ render_view_host->WasResized();
+ did_stop_loading_ = true;
+ if (view_)
+ view_->ShowIfCompletelyLoaded();
+}
+
+ExtensionFunctionDispatcher* ExtensionHost::
+ CreateExtensionFunctionDispatcher(RenderViewHost *render_view_host,
+ const std::string& extension_id) {
+ return new ExtensionFunctionDispatcher(render_view_host, GetBrowser(),
+ extension_id);
+}
+
+RenderViewHostDelegate::View* ExtensionHost::GetViewDelegate() const {
+ // TODO(erikkay) this is unfortunate. The interface declares that this method
+ // must be const (no good reason for it as far as I can tell) which means you
+ // can't return self without doing this const_cast. Either we need to change
+ // the interface, or we need to split out the view delegate into another
+ // object (which is how WebContents works).
+ return const_cast<ExtensionHost*>(this);
+}
+
+void ExtensionHost::CreateNewWindow(int route_id,
+ base::WaitableEvent* modal_dialog_event) {
+ delegate_view_helper_.CreateNewWindow(
+ route_id, modal_dialog_event, render_view_host()->process()->profile(),
+ site_instance());
+}
+
+void ExtensionHost::CreateNewWidget(int route_id, bool activatable) {
+ delegate_view_helper_.CreateNewWidget(route_id, activatable,
+ site_instance()->GetProcess());
+}
+
+void ExtensionHost::ShowCreatedWindow(int route_id,
+ WindowOpenDisposition disposition,
+ const gfx::Rect& initial_pos,
+ bool user_gesture) {
+ WebContents* contents = delegate_view_helper_.GetCreatedWindow(route_id);
+ if (contents) {
+ // TODO(erikkay) is it safe to pass in NULL as source?
+ GetBrowser()->AddTabContents(contents, disposition, initial_pos,
+ user_gesture);
+ }
+}
+
+void ExtensionHost::ShowCreatedWidget(int route_id,
+ const gfx::Rect& initial_pos) {
+ RenderWidgetHostView* widget_host_view =
+ delegate_view_helper_.GetCreatedWidget(route_id);
+ GetBrowser()->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) - This is a temporary hack. Show a menu here instead.
+ render_view_host()->InspectElementAt(params.x, params.y);
+}
+
+void ExtensionHost::StartDragging(const WebDropData& drop_data) {
+}
+
+void ExtensionHost::UpdateDragCursor(bool is_drop_target) {
+}
+
+void ExtensionHost::TakeFocus(bool reverse) {
+}
+
+void ExtensionHost::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {
+}
+
+Browser* ExtensionHost::GetBrowser() {
+ if (view_)
+ return view_->browser();
+ Browser* browser = BrowserList::FindBrowserWithProfile(
+ render_view_host()->process()->profile());
+ // TODO(mpcomplete): what this verifies doesn't actually happen yet.
+ CHECK(browser) << "ExtensionHost running in Profile with no Browser active."
+ " It should have been deleted.";
+ return browser;
+}
diff --git a/chrome/browser/extensions/extension_host.h b/chrome/browser/extensions/extension_host.h
new file mode 100755
index 0000000..0c67be8
--- /dev/null
+++ b/chrome/browser/extensions/extension_host.h
@@ -0,0 +1,100 @@
+// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_HOST_H_
+#define CHROME_BROWSER_EXTENSIONS_EXTENSION_HOST_H_
+
+#include "chrome/browser/renderer_host/render_view_host_delegate.h"
+#include "chrome/browser/tab_contents/render_view_host_delegate_helper.h"
+
+class Browser;
+class Extension;
+class ExtensionView;
+class RenderWidgetHost;
+class RenderWidgetHostView;
+class WebContents;
+struct WebPreferences;
+
+// This class is the browser component of an extension component's RenderView.
+// 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
+// in the browser UI, or it may be hidden.
+class ExtensionHost : public RenderViewHostDelegate,
+ public RenderViewHostDelegate::View {
+ public:
+ ExtensionHost(Extension* extension, SiteInstance* site_instance);
+ ~ExtensionHost();
+
+ void set_view(ExtensionView* view) { view_ = view; }
+ ExtensionView* view() const { return view_; }
+ Extension* extension() { return extension_; }
+ RenderViewHost* render_view_host() const { return render_view_host_; }
+ SiteInstance* site_instance() const;
+ bool did_stop_loading() const { return did_stop_loading_; }
+
+ // Initializes our RenderViewHost by creating its RenderView and navigating
+ // to the given URL. Uses host_view for the RenderViewHost's view (can be
+ // NULL).
+ void CreateRenderView(const GURL& url, RenderWidgetHostView* host_view);
+
+ // RenderViewHostDelegate
+ // TODO(mpcomplete): GetProfile is unused.
+ virtual Profile* GetProfile() const { return NULL; }
+ virtual void RenderViewCreated(RenderViewHost* render_view_host);
+ virtual void DidContentsPreferredWidthChange(const int pref_width);
+ virtual WebPreferences GetWebkitPrefs();
+ virtual void RunJavaScriptMessage(
+ const std::wstring& message,
+ const std::wstring& default_prompt,
+ const GURL& frame_url,
+ const int flags,
+ IPC::Message* reply_msg,
+ bool* did_suppress_message);
+ virtual void DidStartLoading(RenderViewHost* render_view_host);
+ virtual void DidStopLoading(RenderViewHost* render_view_host);
+ virtual RenderViewHostDelegate::View* GetViewDelegate() const;
+ virtual ExtensionFunctionDispatcher* CreateExtensionFunctionDispatcher(
+ RenderViewHost *render_view_host, const std::string& extension_id);
+
+ // RenderViewHostDelegate::View
+ virtual void CreateNewWindow(int route_id,
+ base::WaitableEvent* modal_dialog_event);
+ virtual void CreateNewWidget(int route_id, bool activatable);
+ virtual void ShowCreatedWindow(int route_id,
+ WindowOpenDisposition disposition,
+ const gfx::Rect& initial_pos,
+ bool user_gesture);
+ virtual void ShowCreatedWidget(int route_id,
+ const gfx::Rect& initial_pos);
+ virtual void ShowContextMenu(const ContextMenuParams& params);
+ virtual void StartDragging(const WebDropData& drop_data);
+ virtual void UpdateDragCursor(bool is_drop_target);
+ virtual void TakeFocus(bool reverse);
+ virtual void HandleKeyboardEvent(const NativeWebKeyboardEvent& event);
+
+ private:
+ // If this ExtensionHost has a view, this returns the Browser that view is a
+ // part of. If this is a global background page, we use the active Browser
+ // instead.
+ Browser* GetBrowser();
+
+ // The extension that we're hosting in this view.
+ Extension* extension_;
+
+ // Optional view that shows the rendered content in the UI.
+ ExtensionView* view_;
+
+ // The host for our HTML content.
+ RenderViewHost* render_view_host_;
+
+ // Common implementations of some RenderViewHostDelegate::View methods.
+ RenderViewHostDelegateViewHelper delegate_view_helper_;
+
+ // Whether the RenderWidget has reported that it has stopped loading.
+ bool did_stop_loading_;
+
+ DISALLOW_COPY_AND_ASSIGN(ExtensionHost);
+};
+
+#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_HOST_H_
diff --git a/chrome/browser/extensions/extension_view.cc b/chrome/browser/extensions/extension_view.cc
index b394af7..5678e08 100755
--- a/chrome/browser/extensions/extension_view.cc
+++ b/chrome/browser/extensions/extension_view.cc
@@ -4,65 +4,65 @@
#include "chrome/browser/extensions/extension_view.h"
-#include "base/command_line.h"
-#include "chrome/browser/browser.h"
-#include "chrome/browser/character_encoding.h"
-#include "chrome/browser/extensions/extension.h"
-#include "chrome/browser/extensions/extension_message_service.h"
-#include "chrome/browser/jsmessage_box_handler.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/renderer_host/render_view_host.h"
-#include "chrome/browser/renderer_host/render_process_host.h"
-#include "chrome/browser/renderer_host/render_widget_host.h"
#include "chrome/browser/renderer_host/render_widget_host_view.h"
-#include "chrome/browser/tab_contents/site_instance.h"
-#include "chrome/browser/tab_contents/web_contents.h"
-#include "chrome/browser/tab_contents/tab_contents_view.h"
-#include "chrome/common/chrome_switches.h"
-#include "chrome/common/pref_names.h"
-#include "chrome/common/pref_service.h"
-#include "chrome/common/resource_bundle.h"
-
-#include "grit/browser_resources.h"
-#include "grit/generated_resources.h"
-
-#include "webkit/glue/context_menu.h"
-
-ExtensionView::ExtensionView(Extension* extension,
- const GURL& url,
- SiteInstance* instance,
- Browser* browser)
- : HWNDHtmlView(url, this, false, instance),
- extension_(extension),
- browser_(browser),
- did_stop_loading_(false),
- pending_preferred_width_(0) {
+#include "chrome/views/widget/widget.h"
+
+#if defined(OS_WIN)
+#include "chrome/browser/renderer_host/render_widget_host_view_win.h"
+#endif
+
+ExtensionView::ExtensionView(ExtensionHost* host, Browser* browser,
+ const GURL& content_url)
+ : host_(host), browser_(browser), content_url_(content_url),
+ initialized_(false) {
+ host_->set_view(this);
+}
+
+ExtensionView::~ExtensionView() {
+ if (GetHWND())
+ Detach();
}
-ExtensionFunctionDispatcher* ExtensionView::
- CreateExtensionFunctionDispatcher(RenderViewHost *render_view_host,
- const std::string& extension_id) {
- return new ExtensionFunctionDispatcher(render_view_host, browser_,
- extension_id);
+void ExtensionView::SetVisible(bool is_visible) {
+ HWNDView::SetVisible(is_visible);
+
+ // Also tell RenderWidgetHostView the new visibility. Despite its name, it is
+ // not part of the View heirarchy and does not know about the change unless we
+ // tell it.
+ if (render_view_host()->view()) {
+ if (is_visible)
+ render_view_host()->view()->Show();
+ else
+ render_view_host()->view()->Hide();
+ }
+}
+
+void ExtensionView::DidChangeBounds(const gfx::Rect& previous,
+ const gfx::Rect& current) {
+ // Propagate the new size to RenderWidgetHostView.
+ // We can't send size zero because RenderWidget DCHECKs that.
+ if (render_view_host()->view() && !current.IsEmpty())
+ render_view_host()->view()->SetSize(gfx::Size(width(), height()));
}
void ExtensionView::ShowIfCompletelyLoaded() {
// We wait to show the ExtensionView until it has loaded and our parent has
// given us a background. These can happen in different orders.
- if (did_stop_loading_ && !render_view_host()->view()->background().empty()) {
+ if (host_->did_stop_loading() && render_view_host()->view() &&
+ !render_view_host()->view()->background().empty()) {
SetVisible(true);
DidContentsPreferredWidthChange(pending_preferred_width_);
}
}
void ExtensionView::SetBackground(const SkBitmap& background) {
- HWNDHtmlView::SetBackground(background);
- ShowIfCompletelyLoaded();
-}
-
-void ExtensionView::DidStopLoading(RenderViewHost* render_view_host) {
- render_view_host->WasResized();
- did_stop_loading_ = true;
+ if (initialized_ && render_view_host()->view()) {
+ render_view_host()->view()->SetBackground(background);
+ } else {
+ pending_background_ = background;
+ }
ShowIfCompletelyLoaded();
}
@@ -87,97 +87,37 @@ void ExtensionView::DidContentsPreferredWidthChange(const int pref_width) {
}
}
-void ExtensionView::CreatingRenderer() {
- render_view_host()->AllowExtensionBindings();
- SetVisible(false);
-}
-
-void ExtensionView::RenderViewCreated(RenderViewHost* rvh) {
- URLRequestContext* context = rvh->process()->profile()->GetRequestContext();
- ExtensionMessageService::GetInstance(context)->RegisterExtension(
- extension_->id(), render_view_host()->process()->pid());
-}
-
-WebPreferences ExtensionView::GetWebkitPrefs() {
- PrefService* prefs = render_view_host()->process()->profile()->GetPrefs();
- bool isDomUI = true;
- return RenderViewHostDelegateHelper::GetWebkitPrefs(prefs, isDomUI);
-}
-
-void ExtensionView::RunJavaScriptMessage(
- const std::wstring& message,
- const std::wstring& default_prompt,
- const GURL& frame_url,
- const int flags,
- IPC::Message* reply_msg,
- bool* did_suppress_message) {
- // Automatically cancel the javascript alert (otherwise the renderer hangs
- // indefinitely).
- *did_suppress_message = true;
- render_view_host()->JavaScriptMessageBoxClosed(reply_msg, true, L"");
-}
-
-void ExtensionView::DidStartLoading(RenderViewHost* render_view_host) {
- static const StringPiece toolstrip_css(
- ResourceBundle::GetSharedInstance().GetRawDataResource(
- IDR_EXTENSIONS_TOOLSTRIP_CSS));
- render_view_host->InsertCSSInWebFrame(L"", toolstrip_css.as_string());
-}
-
-RenderViewHostDelegate::View* ExtensionView::GetViewDelegate() const {
- // TODO(erikkay) this is unfortunate. The interface declares that this method
- // must be const (no good reason for it as far as I can tell) which means you
- // can't return self without doing this const_cast. Either we need to change
- // the interface, or we need to split out the view delegate into another
- // object (which is how WebContents works).
- return const_cast<ExtensionView*>(this);
-}
-
-void ExtensionView::CreateNewWindow(int route_id,
- base::WaitableEvent* modal_dialog_event) {
- delegate_view_helper_.CreateNewWindow(route_id, modal_dialog_event,
- browser_->profile(), site_instance());
-}
-
-void ExtensionView::CreateNewWidget(int route_id, bool activatable) {
- delegate_view_helper_.CreateNewWidget(route_id, activatable,
- site_instance()->GetProcess());
-}
-
-void ExtensionView::ShowCreatedWindow(int route_id,
- WindowOpenDisposition disposition,
- const gfx::Rect& initial_pos,
- bool user_gesture) {
- WebContents* contents = delegate_view_helper_.GetCreatedWindow(route_id);
- if (contents) {
- browser_->AddTabContents(contents, disposition, initial_pos, user_gesture);
+void ExtensionView::ViewHierarchyChanged(bool is_add,
+ views::View *parent,
+ views::View *child) {
+ if (is_add && GetWidget() && !initialized_) {
+ initialized_ = true;
+
+ RenderWidgetHostView* view = RenderWidgetHostView::CreateViewForWidget(
+ render_view_host());
+
+ // TODO(mpcomplete): RWHV needs a cross-platform Init function.
+#if defined(OS_WIN)
+ // Create the HWND. Note:
+ // RenderWidgetHostHWND supports windowed plugins, but if we ever also
+ // wanted to support constrained windows with this, we would need an
+ // additional HWND to parent off of because windowed plugin HWNDs cannot
+ // exist in the same z-order as constrained windows.
+ RenderWidgetHostViewWin* view_win =
+ static_cast<RenderWidgetHostViewWin*>(view);
+ HWND hwnd = view_win->Create(GetWidget()->GetNativeView());
+ view_win->ShowWindow(SW_SHOW);
+ Attach(hwnd);
+#else
+ NOTIMPLEMENTED();
+#endif
+
+ host_->CreateRenderView(content_url_, view);
+ SetVisible(false);
+
+ if (!pending_background_.empty()) {
+ render_view_host()->view()->SetBackground(pending_background_);
+ pending_background_.reset();
+ }
}
}
-
-void ExtensionView::ShowCreatedWidget(int route_id,
- const gfx::Rect& initial_pos) {
- RenderWidgetHostView* widget_host_view =
- delegate_view_helper_.GetCreatedWidget(route_id);
- 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 ExtensionView::ShowContextMenu(const ContextMenuParams& params) {
- // TODO(erikkay) - This is a temporary hack. Show a menu here instead.
- render_view_host()->InspectElementAt(params.x, params.y);
-}
-
-void ExtensionView::StartDragging(const WebDropData& drop_data) {
-}
-
-void ExtensionView::UpdateDragCursor(bool is_drop_target) {
-}
-
-void ExtensionView::TakeFocus(bool reverse) {
-}
-
-void ExtensionView::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {
-}
diff --git a/chrome/browser/extensions/extension_view.h b/chrome/browser/extensions/extension_view.h
index 38e093d..7715c5b 100755
--- a/chrome/browser/extensions/extension_view.h
+++ b/chrome/browser/extensions/extension_view.h
@@ -5,97 +5,68 @@
#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_VIEW_H_
#define CHROME_BROWSER_EXTENSIONS_EXTENSION_VIEW_H_
-#include "chrome/browser/renderer_host/render_view_host_delegate.h"
-#include "chrome/browser/tab_contents/render_view_host_delegate_helper.h"
+#include "build/build_config.h"
+
+#include "base/scoped_ptr.h"
+#include "chrome/browser/extensions/extension_host.h"
+#include "googleurl/src/gurl.h"
#include "skia/include/SkBitmap.h"
// TODO(port): Port these files.
#if defined(OS_WIN)
-#include "chrome/browser/views/hwnd_html_view.h"
+#include "chrome/views/controls/hwnd_view.h"
#else
+#include "chrome/views/view.h"
#include "chrome/common/temp_scaffolding_stubs.h"
#endif
class Browser;
class Extension;
-class ExtensionFunctionDispatcher;
-class RenderWidgetHost;
-class RenderWidgetHostView;
-class WebContents;
-struct WebPreferences;
-
-// This class is the browser component of an extension component's RenderView.
-// It handles setting up the renderer process, if needed, with special
-// priviliges available to extensions. The view may be drawn to the screen or
-// hidden.
-class ExtensionView : public HWNDHtmlView,
- public RenderViewHostDelegate,
- public RenderViewHostDelegate::View {
- public:
- // ExtensionView
- ExtensionView(Extension* extension,
- const GURL& url,
- SiteInstance* instance,
- Browser* browser);
-
- Extension* extension() { return extension_; }
-
- // HWNDHtmlView
- virtual void CreatingRenderer();
-
- virtual void SetBackground(const SkBitmap& background);
-
- // RenderViewHostDelegate
- // TODO(mpcomplete): GetProfile is unused.
- virtual Profile* GetProfile() const { return NULL; }
- virtual ExtensionFunctionDispatcher *CreateExtensionFunctionDispatcher(
- RenderViewHost *render_view_host,
- const std::string& extension_id);
- virtual void RenderViewCreated(RenderViewHost* render_view_host);
- virtual void DidContentsPreferredWidthChange(const int pref_width);
- virtual void DidStopLoading(RenderViewHost* render_view_host);
- virtual WebPreferences GetWebkitPrefs();
- virtual void RunJavaScriptMessage(
- const std::wstring& message,
- const std::wstring& default_prompt,
- const GURL& frame_url,
- const int flags,
- IPC::Message* reply_msg,
- bool* did_suppress_message);
- virtual void DidStartLoading(RenderViewHost* render_view_host);
- virtual RenderViewHostDelegate::View* GetViewDelegate() const;
-
- // RenderViewHostDelegate::View
- virtual void CreateNewWindow(int route_id,
- base::WaitableEvent* modal_dialog_event);
- virtual void CreateNewWidget(int route_id, bool activatable);
- virtual void ShowCreatedWindow(int route_id,
- WindowOpenDisposition disposition,
- const gfx::Rect& initial_pos,
- bool user_gesture);
- virtual void ShowCreatedWidget(int route_id,
- const gfx::Rect& initial_pos);
- virtual void ShowContextMenu(const ContextMenuParams& params);
- virtual void StartDragging(const WebDropData& drop_data);
- virtual void UpdateDragCursor(bool is_drop_target);
- virtual void TakeFocus(bool reverse);
- virtual void HandleKeyboardEvent(const NativeWebKeyboardEvent& event);
+// This handles the display portion of an ExtensionHost.
+class ExtensionView : public views::HWNDView {
+ public:
+ ExtensionView(ExtensionHost* host, Browser* browser, const GURL& content_url);
+ ~ExtensionView();
+
+ ExtensionHost* host() const { return host_.get(); }
+ Browser* browser() const { return browser_; }
+ Extension* extension() { return host_->extension(); }
+ RenderViewHost* render_view_host() { return host_->render_view_host(); }
+
+ // Notification from ExtensionHost.
+ void DidContentsPreferredWidthChange(const int pref_width);
+
+ // Set a custom background for the view. The background will be tiled.
+ void SetBackground(const SkBitmap& background);
+
+ // views::HWNDView
+ virtual void SetVisible(bool is_visible);
+ virtual void DidChangeBounds(const gfx::Rect& previous,
+ const gfx::Rect& current);
+ virtual void ViewHierarchyChanged(bool is_add,
+ views::View *parent, views::View *child);
private:
+ friend class ExtensionHost;
+
// We wait to show the ExtensionView until several things have loaded.
void ShowIfCompletelyLoaded();
- // The extension that we're hosting in this view.
- Extension* extension_;
+ // The running extension instance that we're displaying.
+ scoped_ptr<ExtensionHost> host_;
// The browser window that this view is in.
Browser* browser_;
- // Common implementations of some RenderViewHostDelegate::View methods.
- RenderViewHostDelegateViewHelper delegate_view_helper_;
+ // The URL to navigate the host to upon initialization.
+ GURL content_url_;
+
+ // True if we've been initialized.
+ bool initialized_;
- // Whether the RenderWidget has reported that it has stopped loading.
- bool did_stop_loading_;
+ // The background the view should have once it is initialized. This is set
+ // when the view has a custom background, but hasn't been initialized yet.
+ SkBitmap pending_background_;
// What we should set the preferred width to once the ExtensionView has
// loaded.
diff --git a/chrome/browser/extensions/extension_view_unittest.cc b/chrome/browser/extensions/extension_view_unittest.cc
index e1c3d8d..3529022 100755
--- a/chrome/browser/extensions/extension_view_unittest.cc
+++ b/chrome/browser/extensions/extension_view_unittest.cc
@@ -6,7 +6,7 @@
#include "chrome/browser/browser.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/extensions/extension_error_reporter.h"
-#include "chrome/browser/extensions/extension_view.h"
+#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/extensions/test_extension_loader.h"
#include "chrome/browser/tab_contents/site_instance.h"
@@ -28,12 +28,13 @@ const char* kExtensionId = "00123456789abcdef0123456789abcdef0123456";
// This class starts up an extension process and waits until it tries to put
// up a javascript alert.
-class MockExtensionView : public ExtensionView {
+class MockExtensionHost : public ExtensionHost {
public:
- MockExtensionView(Extension* extension, const GURL& url,
- SiteInstance* instance, Browser* browser)
- : ExtensionView(extension, url, instance, browser), got_message_(false) {
- InitHidden();
+ MockExtensionHost(Extension* extension, const GURL& url,
+ SiteInstance* instance)
+ : ExtensionHost(extension, instance),
+ got_message_(false) {
+ CreateRenderView(url, NULL);
MessageLoop::current()->PostDelayedTask(FROM_HERE,
new MessageLoop::QuitTask, kAlertTimeoutMs);
ui_test_utils::RunMessageLoop();
@@ -58,7 +59,7 @@ class MockExtensionView : public ExtensionView {
MessageLoopForUI::current()->Quit();
// Call super, otherwise we'll leak reply_msg.
- ExtensionView::RunJavaScriptMessage(
+ ExtensionHost::RunJavaScriptMessage(
message, default_prompt, frame_url, flags,
reply_msg, did_suppress_message);
}
@@ -100,8 +101,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionViewTest, Index) {
GURL url = Extension::GetResourceURL(extension->url(), "toolstrip1.html");
// Start the extension process and wait for it to show a javascript alert.
- MockExtensionView view(extension, url,
- browser()->profile()->GetExtensionsService()->GetSiteInstanceForURL(url),
- browser());
- EXPECT_TRUE(view.got_message());
+ MockExtensionHost host(extension, url,
+ browser()->profile()->GetExtensionsService()->GetSiteInstanceForURL(url));
+ EXPECT_TRUE(host.got_message());
}
diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc
index b645dfe..38fb703 100644
--- a/chrome/browser/extensions/extensions_service.cc
+++ b/chrome/browser/extensions/extensions_service.cc
@@ -18,8 +18,9 @@
#include "chrome/browser/extensions/extension.h"
#include "chrome/browser/extensions/extension_browser_event_router.h"
#include "chrome/browser/extensions/extension_error_reporter.h"
-#include "chrome/browser/extensions/user_script_master.h"
+#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_view.h"
+#include "chrome/browser/extensions/user_script_master.h"
#include "chrome/browser/plugin_service.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/site_instance.h"
@@ -27,6 +28,8 @@
#include "chrome/common/notification_service.h"
#include "chrome/common/unzip.h"
+#include "chrome/browser/browser_list.h"
+
#if defined(OS_WIN)
#include "base/registry.h"
#endif
@@ -82,6 +85,11 @@ ExtensionsService::ExtensionsService(Profile* profile,
}
ExtensionsService::~ExtensionsService() {
+ for (ExtensionHostList::iterator iter = background_hosts_.begin();
+ iter != background_hosts_.end(); ++iter) {
+ delete *iter;
+ }
+
for (ExtensionList::iterator iter = extensions_.begin();
iter != extensions_.end(); ++iter) {
delete *iter;
@@ -163,6 +171,11 @@ void ExtensionsService::OnExtensionsLoaded(ExtensionList* new_extensions) {
script != scripts.end(); ++script) {
user_script_master_->AddLoneScript(*script);
}
+
+ // Start the process for the master page, if it exists.
+ if ((*extension)->background_url().is_valid()) {
+ CreateBackgroundHost(*extension, (*extension)->background_url());
+ }
}
// Since user scripts may have changed, tell UserScriptMaster to kick off
@@ -189,7 +202,16 @@ void ExtensionsService::OnExtensionInstalled(FilePath path, bool update) {
ExtensionView* ExtensionsService::CreateView(Extension* extension,
const GURL& url,
Browser* browser) {
- return new ExtensionView(extension, url, GetSiteInstanceForURL(url), browser);
+ return new ExtensionView(
+ new ExtensionHost(extension, GetSiteInstanceForURL(url)), browser, url);
+}
+
+void ExtensionsService::CreateBackgroundHost(Extension* extension,
+ const GURL& url) {
+ ExtensionHost* host =
+ new ExtensionHost(extension, GetSiteInstanceForURL(url));
+ host->CreateRenderView(url, NULL); // create a RenderViewHost with no view
+ background_hosts_.push_back(host);
}
SiteInstance* ExtensionsService::GetSiteInstanceForURL(const GURL& url) {
diff --git a/chrome/browser/extensions/extensions_service.h b/chrome/browser/extensions/extensions_service.h
index 2d075bc..d876f34 100644
--- a/chrome/browser/extensions/extensions_service.h
+++ b/chrome/browser/extensions/extensions_service.h
@@ -7,6 +7,7 @@
#include <string>
#include <vector>
+#include <list>
#include "base/file_path.h"
#include "base/message_loop.h"
@@ -17,6 +18,7 @@
class Browser;
class BrowsingInstance;
class Extension;
+class ExtensionHost;
class ExtensionView;
class ExtensionsServiceBackend;
class GURL;
@@ -82,6 +84,10 @@ class ExtensionsService : public ExtensionsServiceFrontendInterface {
const GURL& url,
Browser* browser);
+ // Creates a new UI-less extension instance. Like CreateView, but not
+ // displayed anywhere.
+ void CreateBackgroundHost(Extension* extension, const GURL& url);
+
// Returns the SiteInstance that the given URL belongs to.
SiteInstance* GetSiteInstanceForURL(const GURL& url);
@@ -112,6 +118,10 @@ class ExtensionsService : public ExtensionsServiceFrontendInterface {
// controls process grouping.
scoped_refptr<BrowsingInstance> browsing_instance_;
+ // The list of running viewless background extensions.
+ typedef std::list<ExtensionHost*> ExtensionHostList;
+ ExtensionHostList background_hosts_;
+
DISALLOW_COPY_AND_ASSIGN(ExtensionsService);
};
diff --git a/chrome/browser/extensions/extensions_service_unittest.cc b/chrome/browser/extensions/extensions_service_unittest.cc
index 685f914..b4a81c5 100644
--- a/chrome/browser/extensions/extensions_service_unittest.cc
+++ b/chrome/browser/extensions/extensions_service_unittest.cc
@@ -184,6 +184,7 @@ TEST_F(ExtensionsServiceTest, LoadAllExtensionsFromDirectorySuccess) {
scripts[0].js_scripts()[0].path().value());
EXPECT_EQ(extension->path().AppendASCII("script2.js").value(),
scripts[0].js_scripts()[1].path().value());
+ EXPECT_TRUE(extension->plugins_dir().empty());
EXPECT_EQ(1u, scripts[1].url_patterns().size());
EXPECT_EQ("http://*.news.com/*", scripts[1].url_patterns()[0].GetAsString());
EXPECT_EQ(extension->path().AppendASCII("js_files").AppendASCII("script3.js")
@@ -204,6 +205,8 @@ TEST_F(ExtensionsServiceTest, LoadAllExtensionsFromDirectorySuccess) {
frontend->extensions()->at(1)->description());
EXPECT_EQ(frontend->extensions()->at(1)->path().AppendASCII("npapi").value(),
frontend->extensions()->at(1)->plugins_dir().value());
+ EXPECT_EQ(frontend->extensions()->at(1)->GetResourceURL("background.html"),
+ frontend->extensions()->at(1)->background_url());
ASSERT_EQ(0u, frontend->extensions()->at(1)->content_scripts().size());
EXPECT_EQ(std::string("20123456789abcdef0123456789abcdef0123456"),
diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc
index d778250..3646358 100644
--- a/chrome/browser/renderer_host/render_view_host.cc
+++ b/chrome/browser/renderer_host/render_view_host.cc
@@ -160,14 +160,12 @@ bool RenderViewHost::CreateRenderView() {
"Couldn't duplicate the modal dialog handle for the renderer.";
#endif
- DCHECK(view());
-
ModalDialogEvent modal_dialog_event;
#if defined(OS_WIN)
modal_dialog_event.event = modal_dialog_event_handle;
#endif
- Send(new ViewMsg_New(gfx::IdFromNativeView(view()->GetPluginNativeView()),
+ Send(new ViewMsg_New(GetPluginNativeViewId(),
modal_dialog_event,
delegate_->GetWebkitPrefs(),
routing_id()));
diff --git a/chrome/browser/renderer_host/render_widget_host.cc b/chrome/browser/renderer_host/render_widget_host.cc
index 9e07de7..7a2122a 100644
--- a/chrome/browser/renderer_host/render_widget_host.cc
+++ b/chrome/browser/renderer_host/render_widget_host.cc
@@ -4,7 +4,6 @@
#include "chrome/browser/renderer_host/render_widget_host.h"
-#include "base/gfx/native_widget_types.h"
#include "base/histogram.h"
#include "base/message_loop.h"
#include "base/keyboard_codes.h"
@@ -79,15 +78,19 @@ RenderWidgetHost::~RenderWidgetHost() {
process_->Release(routing_id_);
}
+gfx::NativeViewId RenderWidgetHost::GetPluginNativeViewId() {
+ if (view_)
+ return gfx::IdFromNativeView(view_->GetPluginNativeView());
+ return NULL;
+}
+
void RenderWidgetHost::Init() {
DCHECK(process_->channel());
renderer_initialized_ = true;
// Send the ack along with the information on placement.
- gfx::NativeView plugin_view = view_->GetPluginNativeView();
- Send(new ViewMsg_CreatingNew_ACK(routing_id_,
- gfx::IdFromNativeView(plugin_view)));
+ Send(new ViewMsg_CreatingNew_ACK(routing_id_, GetPluginNativeViewId()));
WasResized();
}
@@ -459,7 +462,8 @@ void RenderWidgetHost::OnMsgClose() {
void RenderWidgetHost::OnMsgRequestMove(const gfx::Rect& pos) {
// Note that we ignore the position.
- view_->SetSize(pos.size());
+ if (view_)
+ view_->SetSize(pos.size());
}
void RenderWidgetHost::OnMsgPaintRect(
diff --git a/chrome/browser/renderer_host/render_widget_host.h b/chrome/browser/renderer_host/render_widget_host.h
index 0e93a84..861152a 100644
--- a/chrome/browser/renderer_host/render_widget_host.h
+++ b/chrome/browser/renderer_host/render_widget_host.h
@@ -8,6 +8,7 @@
#include <queue>
#include <vector>
+#include "base/gfx/native_widget_types.h"
#include "base/gfx/size.h"
#include "base/scoped_ptr.h"
#include "base/timer.h"
@@ -267,6 +268,9 @@ class RenderWidgetHost : public IPC::Channel::Listener {
// consistent if a new renderer is created.
void RendererExited();
+ // Retrieves the native view used to contain plugins.
+ gfx::NativeViewId GetPluginNativeViewId();
+
// Called when we an InputEvent was not processed by the renderer. This is
// overridden by RenderView to send upwards to its delegate.
virtual void UnhandledKeyboardEvent(const NativeWebKeyboardEvent& event) {}
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 7820ae4..95bffd2 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -684,6 +684,8 @@
'browser/extensions/extension_function.h',
'browser/extensions/extension_function_dispatcher.cc',
'browser/extensions/extension_function_dispatcher.h',
+ 'browser/extensions/extension_host.cc',
+ 'browser/extensions/extension_host.h',
'browser/extensions/extension_message_service.cc',
'browser/extensions/extension_message_service.h',
'browser/extensions/extension_browser_event_router.cc',
diff --git a/chrome/common/temp_scaffolding_stubs.h b/chrome/common/temp_scaffolding_stubs.h
index c8d77fb..1b49f76 100644
--- a/chrome/common/temp_scaffolding_stubs.h
+++ b/chrome/common/temp_scaffolding_stubs.h
@@ -39,6 +39,7 @@ struct ViewHostMsg_DidPrintPage_Params;
namespace gfx {
class Rect;
+class Widget;
}
namespace IPC {
@@ -478,26 +479,38 @@ class BaseDragSource {
//---------------------------------------------------------------------------
// These stubs are for extensions
-class HWNDHtmlView {
+namespace views {
+class HWNDView {
public:
- HWNDHtmlView(const GURL& content_url, RenderViewHostDelegate* delegate,
- bool allow_dom_ui_bindings, SiteInstance* instance) {
- NOTIMPLEMENTED();
- }
- virtual ~HWNDHtmlView() {}
-
+ int width() { NOTIMPLEMENTED(); return 0; }
int height() { NOTIMPLEMENTED(); return 0; }
- RenderViewHost* render_view_host() { NOTIMPLEMENTED(); return NULL; }
void InitHidden() { NOTIMPLEMENTED(); }
void set_preferred_size(const gfx::Size& size) { NOTIMPLEMENTED(); }
virtual void SetBackground(const SkBitmap&) { NOTIMPLEMENTED(); }
virtual void SetVisible(bool flag) { NOTIMPLEMENTED(); }
void SizeToPreferredSize() { NOTIMPLEMENTED(); }
- HWNDHtmlView* GetParent() const { NOTIMPLEMENTED(); return NULL; }
bool IsVisible() const { NOTIMPLEMENTED(); return false; }
void Layout() { NOTIMPLEMENTED(); }
void SchedulePaint() { NOTIMPLEMENTED(); }
+ HWNDView* GetParent() const { NOTIMPLEMENTED(); return NULL; }
+
+ gfx::NativeWindow GetHWND() { NOTIMPLEMENTED(); return 0; }
+ void Detach() { NOTIMPLEMENTED(); }
+ gfx::Widget* GetWidget() { NOTIMPLEMENTED(); return NULL; }
+};
+} // namespace views
+
+class HWNDHtmlView : public views::HWNDView {
+ public:
+ HWNDHtmlView(const GURL& content_url, RenderViewHostDelegate* delegate,
+ bool allow_dom_ui_bindings, SiteInstance* instance) {
+ NOTIMPLEMENTED();
+ }
+ virtual ~HWNDHtmlView() {}
+
+ RenderViewHost* render_view_host() { NOTIMPLEMENTED(); return NULL; }
SiteInstance* site_instance() { NOTIMPLEMENTED(); return NULL; }
};
+
#endif // CHROME_COMMON_TEMP_SCAFFOLDING_STUBS_H_
diff --git a/chrome/test/data/extensions/good/extension2/2/background.html b/chrome/test/data/extensions/good/extension2/2/background.html
new file mode 100644
index 0000000..741876f
--- /dev/null
+++ b/chrome/test/data/extensions/good/extension2/2/background.html
@@ -0,0 +1 @@
+Dummy file.
diff --git a/chrome/test/data/extensions/good/extension2/2/manifest.json b/chrome/test/data/extensions/good/extension2/2/manifest.json
index 5e148f3..ba13bb7 100644
--- a/chrome/test/data/extensions/good/extension2/2/manifest.json
+++ b/chrome/test/data/extensions/good/extension2/2/manifest.json
@@ -2,5 +2,6 @@
"id": "10123456789ABCDEF0123456789ABCDEF0123456",
"version": "1.0.0.0",
"name": "My extension 2",
- "plugins_dir": "npapi"
+ "plugins_dir": "npapi",
+ "background": "background.html"
}