summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authoraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-25 21:15:02 +0000
committeraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-25 21:15:02 +0000
commita91afcbaed24615861a2c2ddb61ce51827c17e6e (patch)
tree5f6b6d31e3a929559eaa7841501f9f2798b66e85 /chrome
parent02dc409419c556ab9feb505788d02dd21c472101 (diff)
downloadchromium_src-a91afcbaed24615861a2c2ddb61ce51827c17e6e.zip
chromium_src-a91afcbaed24615861a2c2ddb61ce51827c17e6e.tar.gz
chromium_src-a91afcbaed24615861a2c2ddb61ce51827c17e6e.tar.bz2
Re-land 42631: The problem was that notifications aren't implemented on linux/views yet.
TBR=rafaelw@chromium.org git-svn-id: svn://svn.chromium.org/chrome/trunk/src@42671 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/extensions/extension_dom_ui.cc3
-rw-r--r--chrome/browser/extensions/extension_function_dispatcher.cc20
-rw-r--r--chrome/browser/extensions/extension_function_dispatcher.h14
-rw-r--r--chrome/browser/extensions/extension_host.cc4
-rw-r--r--chrome/browser/extensions/fragment_navigation_apitest.cc1
-rw-r--r--chrome/browser/extensions/notifications_apitest.cc15
-rw-r--r--chrome/browser/gtk/notifications/balloon_view_gtk.cc3
-rw-r--r--chrome/browser/gtk/notifications/balloon_view_gtk.h4
-rw-r--r--chrome/browser/gtk/notifications/balloon_view_host_gtk.h2
-rw-r--r--chrome/browser/notifications/balloon_host.cc25
-rw-r--r--chrome/browser/notifications/balloon_host.h26
-rw-r--r--chrome/chrome_tests.gypi1
-rw-r--r--chrome/test/data/extensions/api_test/notifications/has_not_permission/background.html20
-rw-r--r--chrome/test/data/extensions/api_test/notifications/has_not_permission/manifest.json6
-rw-r--r--chrome/test/data/extensions/api_test/notifications/has_not_permission/notification.html3
-rw-r--r--chrome/test/data/extensions/api_test/notifications/has_permission/background.html37
-rw-r--r--chrome/test/data/extensions/api_test/notifications/has_permission/manifest.json6
-rw-r--r--chrome/test/data/extensions/api_test/notifications/has_permission/notification.html12
18 files changed, 176 insertions, 26 deletions
diff --git a/chrome/browser/extensions/extension_dom_ui.cc b/chrome/browser/extensions/extension_dom_ui.cc
index 7ee7339..7d8d15d 100644
--- a/chrome/browser/extensions/extension_dom_ui.cc
+++ b/chrome/browser/extensions/extension_dom_ui.cc
@@ -67,7 +67,8 @@ void ExtensionDOMUI::ResetExtensionFunctionDispatcher(
NavigationController& controller = tab_contents()->controller();
const GURL& url = controller.GetActiveEntry()->url();
extension_function_dispatcher_.reset(
- new ExtensionFunctionDispatcher(render_view_host, this, url));
+ ExtensionFunctionDispatcher::Create(render_view_host, this, url));
+ DCHECK(extension_function_dispatcher_.get());
}
void ExtensionDOMUI::ResetExtensionBookmarkManagerEventRouter() {
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc
index f436d27..76a2300 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.cc
+++ b/chrome/browser/extensions/extension_function_dispatcher.cc
@@ -263,9 +263,26 @@ std::set<ExtensionFunctionDispatcher*>*
return &instances;
}
+ExtensionFunctionDispatcher* ExtensionFunctionDispatcher::Create(
+ RenderViewHost* render_view_host,
+ Delegate* delegate,
+ const GURL& url) {
+ ExtensionsService* service =
+ render_view_host->process()->profile()->GetExtensionsService();
+ DCHECK(service);
+
+ Extension* extension = service->GetExtensionByURL(url);
+ if (extension)
+ return new ExtensionFunctionDispatcher(render_view_host, delegate,
+ extension, url);
+ else
+ return NULL;
+}
+
ExtensionFunctionDispatcher::ExtensionFunctionDispatcher(
RenderViewHost* render_view_host,
Delegate* delegate,
+ Extension* extension,
const GURL& url)
: profile_(render_view_host->process()->profile()),
render_view_host_(render_view_host),
@@ -274,9 +291,6 @@ ExtensionFunctionDispatcher::ExtensionFunctionDispatcher(
ALLOW_THIS_IN_INITIALIZER_LIST(peer_(new Peer(this))) {
// TODO(erikkay) should we do something for these errors in Release?
DCHECK(url.SchemeIs(chrome::kExtensionScheme));
-
- Extension* extension =
- profile()->GetExtensionsService()->GetExtensionByURL(url);
DCHECK(extension);
all_instances()->insert(this);
diff --git a/chrome/browser/extensions/extension_function_dispatcher.h b/chrome/browser/extensions/extension_function_dispatcher.h
index 18cce3b..86342cc 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.h
+++ b/chrome/browser/extensions/extension_function_dispatcher.h
@@ -77,12 +77,15 @@ class ExtensionFunctionDispatcher {
// Resets all functions to their initial implementation.
static void ResetFunctions();
+ // Creates an instance for the specified RenderViewHost and URL. If the URL
+ // does not contain a valid extension, returns NULL.
+ static ExtensionFunctionDispatcher* Create(RenderViewHost* render_view_host,
+ Delegate* delegate,
+ const GURL& url);
+
// Retrieves a vector of all EFD instances.
static std::set<ExtensionFunctionDispatcher*>* all_instances();
- ExtensionFunctionDispatcher(RenderViewHost* render_view_host,
- Delegate* delegate,
- const GURL& url);
~ExtensionFunctionDispatcher();
Delegate* delegate() { return delegate_; }
@@ -123,6 +126,11 @@ class ExtensionFunctionDispatcher {
RenderViewHost* render_view_host() { return render_view_host_; }
private:
+ ExtensionFunctionDispatcher(RenderViewHost* render_view_host,
+ Delegate* delegate,
+ Extension* extension,
+ const GURL& url);
+
// We need to keep a pointer to the profile because we use it in the dtor
// in sending EXTENSION_FUNCTION_DISPATCHER_DESTROYED, but by that point
// the render_view_host_ has been deleted.
diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc
index a57780b..b8baf39 100644
--- a/chrome/browser/extensions/extension_host.cc
+++ b/chrome/browser/extensions/extension_host.cc
@@ -324,7 +324,7 @@ void ExtensionHost::DidNavigate(RenderViewHost* render_view_host,
<< extension_->name();
url_ = params.url;
extension_function_dispatcher_.reset(
- new ExtensionFunctionDispatcher(render_view_host_, this, url_));
+ ExtensionFunctionDispatcher::Create(render_view_host_, this, url_));
}
void ExtensionHost::InsertInfobarCSS() {
@@ -676,7 +676,7 @@ void ExtensionHost::RenderViewCreated(RenderViewHost* render_view_host) {
LOG(INFO) << "(RenderViewCreated) Resetting EFD to " << url_.spec() << " for "
<< extension_->name();
extension_function_dispatcher_.reset(
- new ExtensionFunctionDispatcher(render_view_host, this, url_));
+ ExtensionFunctionDispatcher::Create(render_view_host, this, url_));
if (extension_host_type_ == ViewType::EXTENSION_TOOLSTRIP ||
extension_host_type_ == ViewType::EXTENSION_MOLE ||
diff --git a/chrome/browser/extensions/fragment_navigation_apitest.cc b/chrome/browser/extensions/fragment_navigation_apitest.cc
index 7524c91..00bc536 100644
--- a/chrome/browser/extensions/fragment_navigation_apitest.cc
+++ b/chrome/browser/extensions/fragment_navigation_apitest.cc
@@ -16,4 +16,3 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ExecuteScriptFragmentNavigation) {
const char* extension_name = "executescript/fragment";
ASSERT_TRUE(RunExtensionTest(extension_name)) << message_;
}
-
diff --git a/chrome/browser/extensions/notifications_apitest.cc b/chrome/browser/extensions/notifications_apitest.cc
new file mode 100644
index 0000000..2fd86fa
--- /dev/null
+++ b/chrome/browser/extensions/notifications_apitest.cc
@@ -0,0 +1,15 @@
+// Copyright (c) 2010 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_apitest.h"
+
+
+IN_PROC_BROWSER_TEST_F(ExtensionApiTest, Notifications) {
+#if defined(OS_LINUX) && defined(TOOLKIT_VIEWS)
+ // Notifications not supported on linux/views yet.
+#else
+ ASSERT_TRUE(RunExtensionTest("notifications/has_permission")) << message_;
+ ASSERT_TRUE(RunExtensionTest("notifications/has_not_permission")) << message_;
+#endif
+}
diff --git a/chrome/browser/gtk/notifications/balloon_view_gtk.cc b/chrome/browser/gtk/notifications/balloon_view_gtk.cc
index 3775b5b..b73d6a5 100644
--- a/chrome/browser/gtk/notifications/balloon_view_gtk.cc
+++ b/chrome/browser/gtk/notifications/balloon_view_gtk.cc
@@ -92,7 +92,6 @@ BalloonViewImpl::BalloonViewImpl(BalloonCollection* collection)
: balloon_(NULL),
frame_container_(NULL),
html_container_(NULL),
- html_contents_(NULL),
method_factory_(this),
close_button_(NULL),
animation_(NULL) {
@@ -221,7 +220,7 @@ void BalloonViewImpl::Show(Balloon* balloon) {
options_menu_.reset(new MenuGtk(this, options_menu_model_.get()));
// Create a BalloonViewHost to host the HTML contents of this balloon.
- html_contents_ = new BalloonViewHost(balloon);
+ html_contents_.reset(new BalloonViewHost(balloon));
html_contents_->Init();
gfx::NativeView contents = html_contents_->native_view();
diff --git a/chrome/browser/gtk/notifications/balloon_view_gtk.h b/chrome/browser/gtk/notifications/balloon_view_gtk.h
index 9412cad..289354a 100644
--- a/chrome/browser/gtk/notifications/balloon_view_gtk.h
+++ b/chrome/browser/gtk/notifications/balloon_view_gtk.h
@@ -113,8 +113,8 @@ class BalloonViewImpl : public BalloonView,
// The window that contains the contents of the notification.
GtkWidget* html_container_;
- // The renderer of the HTML contents. Pointer owned by the views hierarchy.
- BalloonViewHost* html_contents_;
+ // The renderer of the HTML contents.
+ scoped_ptr<BalloonViewHost> html_contents_;
// The following factory is used to call methods at a later time.
ScopedRunnableMethodFactory<BalloonViewImpl> method_factory_;
diff --git a/chrome/browser/gtk/notifications/balloon_view_host_gtk.h b/chrome/browser/gtk/notifications/balloon_view_host_gtk.h
index 833a78c..f51b875 100644
--- a/chrome/browser/gtk/notifications/balloon_view_host_gtk.h
+++ b/chrome/browser/gtk/notifications/balloon_view_host_gtk.h
@@ -19,7 +19,7 @@ class BalloonViewHost : public BalloonHost {
explicit BalloonViewHost(Balloon* balloon);
~BalloonViewHost() {
- Shutdown();
+ Shutdown();
}
// Changes the size of the balloon.
diff --git a/chrome/browser/notifications/balloon_host.cc b/chrome/browser/notifications/balloon_host.cc
index 3b4a832..9e9ba28 100644
--- a/chrome/browser/notifications/balloon_host.cc
+++ b/chrome/browser/notifications/balloon_host.cc
@@ -23,8 +23,7 @@ BalloonHost::BalloonHost(Balloon* balloon)
: render_view_host_(NULL),
balloon_(balloon),
initialized_(false),
- should_notify_on_disconnect_(false),
- is_extension_page_(false) {
+ should_notify_on_disconnect_(false) {
DCHECK(balloon_);
// If the notification is for an extension URL, make sure to use the extension
@@ -32,7 +31,6 @@ BalloonHost::BalloonHost(Balloon* balloon)
// extension.
const GURL& balloon_url = balloon_->notification().content_url();
if (balloon_url.SchemeIs(chrome::kExtensionScheme)) {
- is_extension_page_ = true;
site_instance_ =
balloon_->profile()->GetExtensionProcessManager()->GetSiteInstanceForURL(
balloon_url);
@@ -81,6 +79,16 @@ void BalloonHost::RendererGone(RenderViewHost* render_view_host) {
Source<Balloon>(balloon_), NotificationService::NoDetails());
}
+void BalloonHost::ProcessDOMUIMessage(const std::string& message,
+ const Value* content,
+ int request_id,
+ bool has_callback) {
+ if (extension_function_dispatcher_.get()) {
+ extension_function_dispatcher_->HandleRequest(
+ message, content, request_id, has_callback);
+ }
+}
+
// RenderViewHostDelegate::View methods implemented to allow links to
// open pages in new tabs.
void BalloonHost::CreateNewWindow(int route_id) {
@@ -90,9 +98,9 @@ void BalloonHost::CreateNewWindow(int route_id) {
}
void BalloonHost::ShowCreatedWindow(int route_id,
- WindowOpenDisposition disposition,
- const gfx::Rect& initial_pos,
- bool user_gesture) {
+ WindowOpenDisposition disposition,
+ const gfx::Rect& initial_pos,
+ bool user_gesture) {
// Don't allow pop-ups from notifications.
if (disposition == NEW_POPUP)
return;
@@ -115,7 +123,10 @@ void BalloonHost::Init() {
RenderViewHost* rvh = new RenderViewHost(site_instance_.get(),
this, MSG_ROUTING_NONE,
session_storage_namespace_id);
- if (is_extension_page_)
+ extension_function_dispatcher_.reset(
+ ExtensionFunctionDispatcher::Create(
+ rvh, this, balloon_->notification().content_url()));
+ if (extension_function_dispatcher_.get())
rvh->AllowBindings(BindingsPolicy::EXTENSION);
// Do platform-specific initialization.
diff --git a/chrome/browser/notifications/balloon_host.h b/chrome/browser/notifications/balloon_host.h
index b42ea46..b1f47a2 100644
--- a/chrome/browser/notifications/balloon_host.h
+++ b/chrome/browser/notifications/balloon_host.h
@@ -5,6 +5,7 @@
#ifndef CHROME_BROWSER_NOTIFICATIONS_BALLOON_HOST_H_
#define CHROME_BROWSER_NOTIFICATIONS_BALLOON_HOST_H_
+#include "chrome/browser/extensions/extension_function_dispatcher.h"
#include "chrome/browser/notifications/balloon.h"
#include "chrome/browser/notifications/notification.h"
#include "chrome/browser/renderer_host/render_view_host_delegate.h"
@@ -13,10 +14,12 @@
#include "chrome/common/renderer_preferences.h"
#include "webkit/glue/webpreferences.h"
+class Browser;
class Profile;
class BalloonHost : public RenderViewHostDelegate,
- public RenderViewHostDelegate::View {
+ public RenderViewHostDelegate::View,
+ public ExtensionFunctionDispatcher::Delegate {
public:
explicit BalloonHost(Balloon* balloon);
@@ -26,6 +29,16 @@ class BalloonHost : public RenderViewHostDelegate,
// Stops showing the balloon.
void Shutdown();
+ // ExtensionFunctionDispatcher::Delegate overrides.
+ virtual Browser* GetBrowser() const {
+ // Notifications aren't associated with a particular browser.
+ return NULL;
+ }
+ virtual gfx::NativeView GetNativeViewOfHost() {
+ // TODO(aa): Should this return the native view of the BalloonView*?
+ return NULL;
+ }
+
RenderViewHost* render_view_host() const { return render_view_host_; }
// RenderViewHostDelegate overrides.
@@ -50,6 +63,10 @@ class BalloonHost : public RenderViewHostDelegate,
virtual RenderViewHostDelegate::View* GetViewDelegate() {
return this;
}
+ virtual void ProcessDOMUIMessage(const std::string& message,
+ const Value* content,
+ int request_id,
+ bool has_callback);
// RenderViewHostDelegate::View methods. Only the ones for opening new
// windows are currently implemented.
@@ -103,14 +120,15 @@ class BalloonHost : public RenderViewHostDelegate,
// a connection notification has happened and that they happen only once.
bool should_notify_on_disconnect_;
- // Whether the page we are rendering is from an extension.
- bool is_extension_page_;
-
// Site instance for the balloon/profile, to be used for opening new links.
scoped_refptr<SiteInstance> site_instance_;
// Common implementations of some RenderViewHostDelegate::View methods.
RenderViewHostDelegateViewHelper delegate_view_helper_;
+
+ // Handles requests to extension APIs. Will only be non-NULL if we are
+ // rendering a page from an extension.
+ scoped_ptr<ExtensionFunctionDispatcher> extension_function_dispatcher_;
};
#endif // CHROME_BROWSER_NOTIFICATIONS_BALLOON_HOST_H_
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 44c726c..b8db1cb 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1258,6 +1258,7 @@
'browser/extensions/extension_websocket_apitest.cc',
'browser/extensions/fragment_navigation_apitest.cc',
'browser/extensions/isolated_world_apitest.cc',
+ 'browser/extensions/notifications_apitest.cc',
'browser/extensions/page_action_apitest.cc',
'browser/extensions/permissions_apitest.cc',
'browser/extensions/stubs_apitest.cc',
diff --git a/chrome/test/data/extensions/api_test/notifications/has_not_permission/background.html b/chrome/test/data/extensions/api_test/notifications/has_not_permission/background.html
new file mode 100644
index 0000000..f9e23d4b
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/notifications/has_not_permission/background.html
@@ -0,0 +1,20 @@
+<script>
+chrome.test.runTests([
+ function hasPermission() {
+ chrome.test.assertEq(1, // permission not allowed
+ webkitNotifications.checkPermission());
+ chrome.test.succeed();
+ },
+ function showNotification() {
+ try {
+ window.webkitNotifications.createHTMLNotification(
+ chrome.extension.getURL("notification.html")).show();
+ } catch (e) {
+ chrome.test.assertTrue(e.message.indexOf("SECURITY_ERR") == 0);
+ chrome.test.succeed();
+ return;
+ }
+ chrome.test.fail("Expected access denied error.");
+ }
+]);
+</script>
diff --git a/chrome/test/data/extensions/api_test/notifications/has_not_permission/manifest.json b/chrome/test/data/extensions/api_test/notifications/has_not_permission/manifest.json
new file mode 100644
index 0000000..4f7ed68
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/notifications/has_not_permission/manifest.json
@@ -0,0 +1,6 @@
+{
+ "name": "notifications test",
+ "version": "1",
+ "permissions": [ "tabs" ],
+ "background_page": "background.html"
+}
diff --git a/chrome/test/data/extensions/api_test/notifications/has_not_permission/notification.html b/chrome/test/data/extensions/api_test/notifications/has_not_permission/notification.html
new file mode 100644
index 0000000..77cf46f
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/notifications/has_not_permission/notification.html
@@ -0,0 +1,3 @@
+<html>
+Why hello there.
+</html>
diff --git a/chrome/test/data/extensions/api_test/notifications/has_permission/background.html b/chrome/test/data/extensions/api_test/notifications/has_permission/background.html
new file mode 100644
index 0000000..4b43004
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/notifications/has_permission/background.html
@@ -0,0 +1,37 @@
+<script>
+var notification = null;
+
+// Shows the notification window using the specified URL.
+// Control continues at onNotificationDone().
+function showNotification(url) {
+ notification = window.webkitNotifications.createHTMLNotification(url);
+ notification.onerror = function() {
+ chrome.test.fail("Failed to show notification.");
+ };
+ notification.show();
+}
+
+// Called by the notification when it is done with its tests.
+function onNotificationDone() {
+ var views = chrome.extension.getViews();
+ chrome.test.assertEq(2, views.length);
+ notification.cancel();
+ chrome.test.succeed();
+}
+
+chrome.test.runTests([
+ function hasPermission() {
+ chrome.test.assertEq(0, // allowed
+ webkitNotifications.checkPermission());
+ chrome.test.succeed();
+ },
+ function absoluteURL() {
+ showNotification(chrome.extension.getURL("notification.html"));
+ },
+ function relativeURL() {
+ // TODO(aa): Relative URLs don't work for some reason.
+ // BUG: http://crbug.com/39216
+ chrome.test.succeed();
+ }
+]);
+</script>
diff --git a/chrome/test/data/extensions/api_test/notifications/has_permission/manifest.json b/chrome/test/data/extensions/api_test/notifications/has_permission/manifest.json
new file mode 100644
index 0000000..a2fa64f
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/notifications/has_permission/manifest.json
@@ -0,0 +1,6 @@
+{
+ "name": "notifications test",
+ "version": "1",
+ "permissions": [ "notifications", "tabs" ],
+ "background_page": "background.html"
+}
diff --git a/chrome/test/data/extensions/api_test/notifications/has_permission/notification.html b/chrome/test/data/extensions/api_test/notifications/has_permission/notification.html
new file mode 100644
index 0000000..8a78703
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/notifications/has_permission/notification.html
@@ -0,0 +1,12 @@
+<html>
+<script>
+// Test that we can call the tabs API. We don't care what the result is; tabs
+// are tested elsewhere. We just care that we can call it without a
+// permissions error.
+chrome.windows.getAll(null, function() {
+ chrome.test.assertNoLastError();
+ chrome.extension.getBackgroundPage().onNotificationDone();
+});
+</script>
+Why hello there.
+</html>