[WK2] Sync call for notifications permissions causes flashes on gmail.com
authorjonlee@apple.com <jonlee@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Jan 2012 01:14:55 +0000 (01:14 +0000)
committerjonlee@apple.com <jonlee@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Jan 2012 01:14:55 +0000 (01:14 +0000)
https://bugs.webkit.org/show_bug.cgi?id=76570
<rdar://problem/10647155>

Reviewed by Anders Carlsson and Sam Weinig.

Source/WebCore:

* WebCore.exp.in: Export SecurityOrigin::toString().

Add runtime setting to enable/disable notifications.

* page/Settings.cpp:
(WebCore::Settings::Settings):
* page/Settings.h: Add new bit for whether notifications are enabled.
(WebCore::Settings::setNotificationsEnabled):
(WebCore::Settings::notificationsEnabled):

Source/WebKit2:

The website code figures out the permission level for its security origin by making a JS call (called
checkPermission()) that is synchronous. The way this was implemented was to make a synchronous call from
the WebNotificationManager to its proxy. That call goes to the WK API layer to find the policy, and
returns that policy back to the JS.

The synchronous nature of this call causes the white flash to appear in certain cases.

To fix this, the checkPermission() call is handled all within the web process, instead of going up into
the UI process. To do this, the web process initializes the WebNotificationManager with a copy of the
notification permissions. Any time the WK client makes a change to the permissions, that gets sent down
asynchronously, and the cached copy in WebNotificationManager gets updated.

A page's settings may disable notifications altogether. Before, this would have been handled by the WK
client, since retrieving the permissions were also handled there. Now that the lookup happens in the web
process, we need to add that setting in WebCore.

== Update notification permissions to use the security origin's string representation, rather than its
database identifier.

* UIProcess/Notifications/WebNotification.cpp:
(WebKit::WebNotification::WebNotification):
* UIProcess/Notifications/WebNotification.h:
(WebKit::WebNotification::create):
* UIProcess/Notifications/WebNotificationManagerProxy.cpp:
(WebKit::WebNotificationManagerProxy::show): Registering the provider with the manager is handled in
initialize() now.
(WebKit::WebNotificationManagerProxy::cancel): Registering the provider with the manager is handled in
initialize() now.
* UIProcess/Notifications/WebNotificationManagerProxy.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::requestNotificationPermission):
(WebKit::WebPageProxy::showNotification):
* UIProcess/WebPageProxy.h:

* WebProcess/Notifications/NotificationPermissionRequestManager.cpp:
(WebKit::NotificationPermissionRequestManager::startRequest): Only start the request if notifications
are enabled.
* WebProcess/Notifications/WebNotificationManager.cpp:
(WebKit::WebNotificationManager::show): Only show notification is they are enabled.
(WebKit::WebNotificationManager::cancel): Only cancel if notifications are enabled.

== Remove synchronous message to get policy for a given origin. Instead, use the cached copy in
WebNotificationManager.

* WebProcess/Notifications/WebNotificationManager.h:
* WebProcess/Notifications/WebNotificationManager.cpp:
(WebKit::WebNotificationManager::policyForOrigin): Looks for the permission in the cached copy.
If it doesn't exist, return NotificationPresenter::PermissionNotAllowed.
* WebProcess/Notifications/NotificationPermissionRequestManager.cpp:
(WebKit::NotificationPermissionRequestManager::permissionLevel): Update permissionLevel to use
policyForOrigin().

Remove old WK API function to get the policy. Because this function was the only synchronous message,
we remove the sync-message-related functions also. Also, add in some #includes that might have been
omitted in prior patches.

* UIProcess/API/C/WKNotificationProvider.h:
* UIProcess/Notifications/WebNotificationManagerProxy.messages.in: Remove NotificationPermissionLevel.
* UIProcess/Notifications/WebNotificationManagerProxy.h:
* UIProcess/Notifications/WebNotificationManagerProxy.cpp:

* UIProcess/Notifications/WebNotificationProvider.h: Remove policyForNotificationPermissionAtOrigin().
* UIProcess/Notifications/WebNotificationProvider.cpp:

* UIProcess/WebProcessProxy.cpp:
(WebKit::WebProcessProxy::didReceiveSyncMessage): Remove conditional to forward sync messages to the
notification manager proxy.

== Mechanism for client to update the permissions copy in WebNotificationManager.

* WebProcess/Notifications/WebNotificationManager.messages.in: Add new messages
didUpdateNotificationDecision and didRemoveNotificationDecisions.
* WebProcess/Notifications/WebNotificationManager.h:
* WebProcess/Notifications/WebNotificationManager.cpp:
(WebKit::WebNotificationManager::initialize):
(WebKit::WebNotificationManager::didUpdateNotificationDecision): Update the entry.
(WebKit::WebNotificationManager::didRemoveNotificationDecisions): Remove the entry.

* UIProcess/Notifications/WebNotificationManagerProxy.h:
* UIProcess/Notifications/WebNotificationManagerProxy.cpp:
(WebKit::WebNotificationManagerProxy::providerDidUpdateNotificationPolicy):
(WebKit::WebNotificationManagerProxy::providerDidRemoveNotificationPolicies): Convert the array of
origins to remove, and send it to the WebNotificationManager.

* UIProcess/API/C/WKNotificationManager.h: Expose these update functions as WK API.
* UIProcess/API/C/WKNotificationManager.cpp:
(WKNotificationManagerProviderDidUpdateNotificationPolicy):
(WKNotificationManagerProviderDidRemoveNotificationPolicies):

== Initialize WebNotificationManager with permissions. Initialize WebPage with notifications enabled bit
from settings.

* Shared/WebProcessCreationParameters.h: Add map of notification permissions as part of the
parameters.
* Shared/WebProcessCreationParameters.cpp:
(WebKit::WebProcessCreationParameters::encode):
(WebKit::WebProcessCreationParameters::decode):

* UIProcess/Notifications/WebNotificationProvider.h: Retrieve copy of existing notification permissions.
* UIProcess/Notifications/WebNotificationProvider.cpp:
* UIProcess/API/C/WKNotificationProvider.h: Add WK API to get a copy of the permissions.

* UIProcess/Notifications/WebNotificationManagerProxy.h: Add populateCopyOfNotificationPermissions().
* UIProcess/Notifications/WebNotificationManagerProxy.cpp:
(WebKit::WebNotificationManagerProxy::initializeProvider): Add the manager at the time of initialization.
Similar calls in show() and cancel() are removed in following patch.
(WebKit::WebNotificationManagerProxy::populateCopyOfNotificationPermissions): Clear the existing copy.
Populate with origin string, and whether that origin is allowed to post. If no decision has been made
by the user, then there should be no item in this dictionary.

* UIProcess/WebContext.cpp:
(WebKit::WebContext::ensureWebProcess): When the web process is initialized, we get a copy of the
permissions, and send it to the web process to initialize the notification manager.
* WebProcess/mac/WebProcessMac.mm:
(WebKit::WebProcess::platformInitializeWebProcess): Initialize the notification manager.

* WebProcess/Notifications/WebNotificationManager.h:
* WebProcess/Notifications/WebNotificationManager.cpp:
(WebKit::WebNotificationManager::initialize): Initialize the permissions copy.

* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::updatePreferences): Set notifications enabled bit from settings.

== Expose toString() method from WebCore::SecurityOrigin. Work is also towards bug 74956.

* Shared/API/c/WKSecurityOrigin.h: Refactor WKSecurityOriginCreateFromIdentifier to
WKSecurityOriginCreateFromDatabaseIdentifier and add WKSecurityOriginCreateFromString function.
* Shared/API/c/WKSecurityOrigin.cpp:
(WKSecurityOriginCreateFromString):
(WKSecurityOriginCreateFromDatabaseIdentifier):
(WKSecurityOriginCopyToString):

Refactor WebSecurityOrigin::create() to WebSecurityOrigin::createFromDatabaseIdentifier()
and add WebSecurityOrigin::createFromString().

* Shared/WebSecurityOrigin.h:
(WebKit::WebSecurityOrigin::createFromString):
(WebKit::WebSecurityOrigin::createFromDatabaseIdentifier):
(WebKit::WebSecurityOrigin::toString): Added function.

Refactor with renamed createFromDatabaseIdentifier() method.

* UIProcess/WebDatabaseManagerProxy.cpp:
(WebKit::WebDatabaseManagerProxy::didGetDatabasesByOrigin):
(WebKit::WebDatabaseManagerProxy::didGetDatabaseOrigins):
(WebKit::WebDatabaseManagerProxy::didModifyOrigin):
(WebKit::WebDatabaseManagerProxy::didModifyDatabase):
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::exceededDatabaseQuota):
(WebKit::WebPageProxy::requestGeolocationPermissionForFrame):

== Add WK API calls to change notificationsEnabled bit in WebCore::Settings.

* Shared/WebPreferencesStore.h:
* UIProcess/API/C/WKPreferences.cpp:
(WKPreferencesSetNotificationsEnabled):
(WKPreferencesGetNotificationsEnabled):
* UIProcess/API/C/WKPreferences.h:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@105364 268f45cc-cd09-0410-ab3c-d52691b4dbfc

34 files changed:
Source/WebCore/ChangeLog
Source/WebCore/WebCore.exp.in
Source/WebCore/page/Settings.cpp
Source/WebCore/page/Settings.h
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/API/c/WKSecurityOrigin.cpp
Source/WebKit2/Shared/API/c/WKSecurityOrigin.h
Source/WebKit2/Shared/WebPreferencesStore.h
Source/WebKit2/Shared/WebProcessCreationParameters.cpp
Source/WebKit2/Shared/WebProcessCreationParameters.h
Source/WebKit2/Shared/WebSecurityOrigin.h
Source/WebKit2/UIProcess/API/C/WKNotificationManager.cpp
Source/WebKit2/UIProcess/API/C/WKNotificationManager.h
Source/WebKit2/UIProcess/API/C/WKNotificationProvider.h
Source/WebKit2/UIProcess/API/C/WKPreferences.cpp
Source/WebKit2/UIProcess/API/C/WKPreferences.h
Source/WebKit2/UIProcess/Notifications/WebNotification.cpp
Source/WebKit2/UIProcess/Notifications/WebNotification.h
Source/WebKit2/UIProcess/Notifications/WebNotificationManagerProxy.cpp
Source/WebKit2/UIProcess/Notifications/WebNotificationManagerProxy.h
Source/WebKit2/UIProcess/Notifications/WebNotificationManagerProxy.messages.in
Source/WebKit2/UIProcess/Notifications/WebNotificationProvider.cpp
Source/WebKit2/UIProcess/Notifications/WebNotificationProvider.h
Source/WebKit2/UIProcess/WebContext.cpp
Source/WebKit2/UIProcess/WebDatabaseManagerProxy.cpp
Source/WebKit2/UIProcess/WebPageProxy.cpp
Source/WebKit2/UIProcess/WebPageProxy.h
Source/WebKit2/UIProcess/WebProcessProxy.cpp
Source/WebKit2/WebProcess/Notifications/NotificationPermissionRequestManager.cpp
Source/WebKit2/WebProcess/Notifications/WebNotificationManager.cpp
Source/WebKit2/WebProcess/Notifications/WebNotificationManager.h
Source/WebKit2/WebProcess/Notifications/WebNotificationManager.messages.in
Source/WebKit2/WebProcess/WebPage/WebPage.cpp
Source/WebKit2/WebProcess/mac/WebProcessMac.mm

index ec760cb..40202f5 100644 (file)
@@ -1,3 +1,21 @@
+2012-01-18  Jon Lee  <jonlee@apple.com>
+
+        [WK2] Sync call for notifications permissions causes flashes on gmail.com
+        https://bugs.webkit.org/show_bug.cgi?id=76570
+        <rdar://problem/10647155>
+
+        Reviewed by Anders Carlsson and Sam Weinig.
+
+        * WebCore.exp.in: Export SecurityOrigin::toString().
+
+        Add runtime setting to enable/disable notifications.
+
+        * page/Settings.cpp:
+        (WebCore::Settings::Settings):
+        * page/Settings.h: Add new bit for whether notifications are enabled.
+        (WebCore::Settings::setNotificationsEnabled):
+        (WebCore::Settings::notificationsEnabled):
+
 2012-01-18  Eric Carlson  <eric.carlson@apple.com>
 
         Provide access to user's list of preferred languages
index f743862..3db3fc3 100644 (file)
@@ -1259,6 +1259,7 @@ __ZNK7WebCore14ScrollableArea23mouseEnteredContentAreaEv
 __ZNK7WebCore14SecurityOrigin10canDisplayERKNS_4KURLE
 __ZNK7WebCore14SecurityOrigin18databaseIdentifierEv
 __ZNK7WebCore14SecurityOrigin5equalEPKS0_
+__ZNK7WebCore14SecurityOrigin8toStringEv
 __ZNK7WebCore15AffineTransform10isIdentityEv
 __ZNK7WebCore15AffineTransform12isInvertibleEv
 __ZNK7WebCore15AffineTransform7inverseEv
index 403b408..65536fc 100644 (file)
@@ -236,6 +236,7 @@ Settings::Settings(Page* page)
 #if ENABLE(THREADED_SCROLLING)
     , m_scrollingCoordinatorEnabled(false)
 #endif
+    , m_notificationsEnabled(true)
     , m_loadsImagesAutomaticallyTimer(this, &Settings::loadsImagesAutomaticallyTimerFired)
 {
     // A Frame may not have been created yet, so we initialize the AtomicString 
index edece2f..1f77379 100644 (file)
@@ -511,6 +511,9 @@ namespace WebCore {
         bool scrollingCoordinatorEnabled() const { return m_scrollingCoordinatorEnabled; }
 #endif
 
+        void setNotificationsEnabled(bool enabled) { m_notificationsEnabled = enabled; }
+        bool notificationsEnabled() const { return m_notificationsEnabled; }
+
     private:
         Settings(Page*);
 
@@ -652,6 +655,8 @@ namespace WebCore {
         bool m_scrollingCoordinatorEnabled : 1;
 #endif
 
+        bool m_notificationsEnabled : 1;
+
         Timer<Settings> m_loadsImagesAutomaticallyTimer;
         void loadsImagesAutomaticallyTimerFired(Timer<Settings>*);
 
index 28bca5a..b99c91c 100644 (file)
@@ -1,3 +1,170 @@
+2012-01-18  Jon Lee  <jonlee@apple.com>
+
+        [WK2] Sync call for notifications permissions causes flashes on gmail.com
+        https://bugs.webkit.org/show_bug.cgi?id=76570
+        <rdar://problem/10647155>
+
+        Reviewed by Anders Carlsson and Sam Weinig.
+
+        The website code figures out the permission level for its security origin by making a JS call (called
+        checkPermission()) that is synchronous. The way this was implemented was to make a synchronous call from
+        the WebNotificationManager to its proxy. That call goes to the WK API layer to find the policy, and
+        returns that policy back to the JS.
+
+        The synchronous nature of this call causes the white flash to appear in certain cases.
+
+        To fix this, the checkPermission() call is handled all within the web process, instead of going up into
+        the UI process. To do this, the web process initializes the WebNotificationManager with a copy of the
+        notification permissions. Any time the WK client makes a change to the permissions, that gets sent down
+        asynchronously, and the cached copy in WebNotificationManager gets updated.
+
+        A page's settings may disable notifications altogether. Before, this would have been handled by the WK
+        client, since retrieving the permissions were also handled there. Now that the lookup happens in the web
+        process, we need to add that setting in WebCore.
+
+        == Update notification permissions to use the security origin's string representation, rather than its
+        database identifier.
+
+        * UIProcess/Notifications/WebNotification.cpp:
+        (WebKit::WebNotification::WebNotification):
+        * UIProcess/Notifications/WebNotification.h:
+        (WebKit::WebNotification::create):
+        * UIProcess/Notifications/WebNotificationManagerProxy.cpp:
+        (WebKit::WebNotificationManagerProxy::show): Registering the provider with the manager is handled in
+        initialize() now.
+        (WebKit::WebNotificationManagerProxy::cancel): Registering the provider with the manager is handled in
+        initialize() now.
+        * UIProcess/Notifications/WebNotificationManagerProxy.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::requestNotificationPermission):
+        (WebKit::WebPageProxy::showNotification):
+        * UIProcess/WebPageProxy.h:
+
+        * WebProcess/Notifications/NotificationPermissionRequestManager.cpp:
+        (WebKit::NotificationPermissionRequestManager::startRequest): Only start the request if notifications
+        are enabled.
+        * WebProcess/Notifications/WebNotificationManager.cpp:
+        (WebKit::WebNotificationManager::show): Only show notification is they are enabled.
+        (WebKit::WebNotificationManager::cancel): Only cancel if notifications are enabled.
+
+        == Remove synchronous message to get policy for a given origin. Instead, use the cached copy in
+        WebNotificationManager.
+
+        * WebProcess/Notifications/WebNotificationManager.h:
+        * WebProcess/Notifications/WebNotificationManager.cpp:
+        (WebKit::WebNotificationManager::policyForOrigin): Looks for the permission in the cached copy.
+        If it doesn't exist, return NotificationPresenter::PermissionNotAllowed.
+        * WebProcess/Notifications/NotificationPermissionRequestManager.cpp:
+        (WebKit::NotificationPermissionRequestManager::permissionLevel): Update permissionLevel to use
+        policyForOrigin().
+
+        Remove old WK API function to get the policy. Because this function was the only synchronous message,
+        we remove the sync-message-related functions also. Also, add in some #includes that might have been
+        omitted in prior patches.
+
+        * UIProcess/API/C/WKNotificationProvider.h:
+        * UIProcess/Notifications/WebNotificationManagerProxy.messages.in: Remove NotificationPermissionLevel.
+        * UIProcess/Notifications/WebNotificationManagerProxy.h:
+        * UIProcess/Notifications/WebNotificationManagerProxy.cpp:
+
+        * UIProcess/Notifications/WebNotificationProvider.h: Remove policyForNotificationPermissionAtOrigin().
+        * UIProcess/Notifications/WebNotificationProvider.cpp:
+
+        * UIProcess/WebProcessProxy.cpp:
+        (WebKit::WebProcessProxy::didReceiveSyncMessage): Remove conditional to forward sync messages to the
+        notification manager proxy.
+
+        == Mechanism for client to update the permissions copy in WebNotificationManager.
+
+        * WebProcess/Notifications/WebNotificationManager.messages.in: Add new messages
+        didUpdateNotificationDecision and didRemoveNotificationDecisions.
+        * WebProcess/Notifications/WebNotificationManager.h:
+        * WebProcess/Notifications/WebNotificationManager.cpp:
+        (WebKit::WebNotificationManager::initialize):
+        (WebKit::WebNotificationManager::didUpdateNotificationDecision): Update the entry.
+        (WebKit::WebNotificationManager::didRemoveNotificationDecisions): Remove the entry.
+
+        * UIProcess/Notifications/WebNotificationManagerProxy.h:
+        * UIProcess/Notifications/WebNotificationManagerProxy.cpp:
+        (WebKit::WebNotificationManagerProxy::providerDidUpdateNotificationPolicy):
+        (WebKit::WebNotificationManagerProxy::providerDidRemoveNotificationPolicies): Convert the array of
+        origins to remove, and send it to the WebNotificationManager.
+
+        * UIProcess/API/C/WKNotificationManager.h: Expose these update functions as WK API.
+        * UIProcess/API/C/WKNotificationManager.cpp:
+        (WKNotificationManagerProviderDidUpdateNotificationPolicy):
+        (WKNotificationManagerProviderDidRemoveNotificationPolicies):
+
+        == Initialize WebNotificationManager with permissions. Initialize WebPage with notifications enabled bit
+        from settings.
+
+        * Shared/WebProcessCreationParameters.h: Add map of notification permissions as part of the
+        parameters.
+        * Shared/WebProcessCreationParameters.cpp:
+        (WebKit::WebProcessCreationParameters::encode):
+        (WebKit::WebProcessCreationParameters::decode):
+
+        * UIProcess/Notifications/WebNotificationProvider.h: Retrieve copy of existing notification permissions.
+        * UIProcess/Notifications/WebNotificationProvider.cpp:
+        * UIProcess/API/C/WKNotificationProvider.h: Add WK API to get a copy of the permissions.
+
+        * UIProcess/Notifications/WebNotificationManagerProxy.h: Add populateCopyOfNotificationPermissions().
+        * UIProcess/Notifications/WebNotificationManagerProxy.cpp:
+        (WebKit::WebNotificationManagerProxy::initializeProvider): Add the manager at the time of initialization.
+        Similar calls in show() and cancel() are removed in following patch.
+        (WebKit::WebNotificationManagerProxy::populateCopyOfNotificationPermissions): Clear the existing copy.
+        Populate with origin string, and whether that origin is allowed to post. If no decision has been made
+        by the user, then there should be no item in this dictionary.
+
+        * UIProcess/WebContext.cpp:
+        (WebKit::WebContext::ensureWebProcess): When the web process is initialized, we get a copy of the
+        permissions, and send it to the web process to initialize the notification manager.
+        * WebProcess/mac/WebProcessMac.mm:
+        (WebKit::WebProcess::platformInitializeWebProcess): Initialize the notification manager.
+
+        * WebProcess/Notifications/WebNotificationManager.h:
+        * WebProcess/Notifications/WebNotificationManager.cpp:
+        (WebKit::WebNotificationManager::initialize): Initialize the permissions copy.
+
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::updatePreferences): Set notifications enabled bit from settings.
+
+        == Expose toString() method from WebCore::SecurityOrigin. Work is also towards bug 74956.
+
+        * Shared/API/c/WKSecurityOrigin.h: Refactor WKSecurityOriginCreateFromIdentifier to
+        WKSecurityOriginCreateFromDatabaseIdentifier and add WKSecurityOriginCreateFromString function.
+        * Shared/API/c/WKSecurityOrigin.cpp:
+        (WKSecurityOriginCreateFromString):
+        (WKSecurityOriginCreateFromDatabaseIdentifier):
+        (WKSecurityOriginCopyToString):
+
+        Refactor WebSecurityOrigin::create() to WebSecurityOrigin::createFromDatabaseIdentifier()
+        and add WebSecurityOrigin::createFromString().
+
+        * Shared/WebSecurityOrigin.h:
+        (WebKit::WebSecurityOrigin::createFromString):
+        (WebKit::WebSecurityOrigin::createFromDatabaseIdentifier):
+        (WebKit::WebSecurityOrigin::toString): Added function.
+        
+        Refactor with renamed createFromDatabaseIdentifier() method.
+        
+        * UIProcess/WebDatabaseManagerProxy.cpp:
+        (WebKit::WebDatabaseManagerProxy::didGetDatabasesByOrigin):
+        (WebKit::WebDatabaseManagerProxy::didGetDatabaseOrigins):
+        (WebKit::WebDatabaseManagerProxy::didModifyOrigin):
+        (WebKit::WebDatabaseManagerProxy::didModifyDatabase):
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::exceededDatabaseQuota):
+        (WebKit::WebPageProxy::requestGeolocationPermissionForFrame):
+
+        == Add WK API calls to change notificationsEnabled bit in WebCore::Settings.
+
+        * Shared/WebPreferencesStore.h:
+        * UIProcess/API/C/WKPreferences.cpp:
+        (WKPreferencesSetNotificationsEnabled):
+        (WKPreferencesGetNotificationsEnabled):
+        * UIProcess/API/C/WKPreferences.h:
+
 2012-01-18  Anders Carlsson  <andersca@apple.com>
 
         REGRESSION (r88886): Tabs restore blank when running Safari with a nightly build for the first time
index cf7624f..f729106 100644 (file)
@@ -36,9 +36,15 @@ WKTypeID WKSecurityOriginGetTypeID()
     return toAPI(WebSecurityOrigin::APIType);
 }
 
-WKSecurityOriginRef WKSecurityOriginCreateFromIdentifier(WKStringRef identifier)
+WKSecurityOriginRef WKSecurityOriginCreateFromString(WKStringRef string)
 {
-    RefPtr<WebSecurityOrigin> securityOrigin = WebSecurityOrigin::create(toImpl(identifier)->string());
+    RefPtr<WebSecurityOrigin> securityOrigin = WebSecurityOrigin::createFromString(toImpl(string)->string());
+    return toAPI(securityOrigin.release().leakRef());
+}
+
+WKSecurityOriginRef WKSecurityOriginCreateFromDatabaseIdentifier(WKStringRef identifier)
+{
+    RefPtr<WebSecurityOrigin> securityOrigin = WebSecurityOrigin::createFromDatabaseIdentifier(toImpl(identifier)->string());
     return toAPI(securityOrigin.release().leakRef());
 }
 
@@ -53,6 +59,11 @@ WKStringRef WKSecurityOriginCopyDatabaseIdentifier(WKSecurityOriginRef securityO
     return toCopiedAPI(toImpl(securityOrigin)->databaseIdentifier());
 }
 
+WKStringRef WKSecurityOriginCopyToString(WKSecurityOriginRef securityOrigin)
+{
+    return toCopiedAPI(toImpl(securityOrigin)->toString());
+}
+
 WKStringRef WKSecurityOriginCopyProtocol(WKSecurityOriginRef securityOrigin)
 {
     return toCopiedAPI(toImpl(securityOrigin)->protocol());
index 29040d8..d932e93 100644 (file)
@@ -34,10 +34,12 @@ extern "C" {
 
 WK_EXPORT WKTypeID WKSecurityOriginGetTypeID();
 
-WK_EXPORT WKSecurityOriginRef WKSecurityOriginCreateFromIdentifier(WKStringRef identifier);
+WK_EXPORT WKSecurityOriginRef WKSecurityOriginCreateFromString(WKStringRef string);
+WK_EXPORT WKSecurityOriginRef WKSecurityOriginCreateFromDatabaseIdentifier(WKStringRef identifier);
 WK_EXPORT WKSecurityOriginRef WKSecurityOriginCreate(WKStringRef protocol, WKStringRef host, int port);
 
 WK_EXPORT WKStringRef WKSecurityOriginCopyDatabaseIdentifier(WKSecurityOriginRef securityOrigin);
+WK_EXPORT WKStringRef WKSecurityOriginCopyToString(WKSecurityOriginRef securityOrigin);
 WK_EXPORT WKStringRef WKSecurityOriginCopyProtocol(WKSecurityOriginRef securityOrigin);
 WK_EXPORT WKStringRef WKSecurityOriginCopyHost(WKSecurityOriginRef securityOrigin);
 WK_EXPORT unsigned short WKSecurityOriginGetPort(WKSecurityOriginRef securityOrigin);
index 6b0a143..be7caab 100644 (file)
@@ -102,6 +102,7 @@ namespace WebKit {
     macro(ShouldDisplaySubtitles, shouldDisplaySubtitles, Bool, bool, false) \
     macro(ShouldDisplayCaptions, shouldDisplayCaptions, Bool, bool, false) \
     macro(ShouldDisplayTextDescriptions, shouldDisplayTextDescriptions, Bool, bool, false) \
+    macro(NotificationsEnabled, notificationsEnabled, Bool, bool, true) \
     \
 
 #define FOR_EACH_WEBKIT_DOUBLE_PREFERENCE(macro) \
index 2ee7ad0..8e1d164 100644 (file)
@@ -99,6 +99,10 @@ void WebProcessCreationParameters::encode(CoreIPC::ArgumentEncoder* encoder) con
 #if PLATFORM(QT)
     encoder->encode(cookieStorageDirectory);
 #endif
+
+#if ENABLE(NOTIFICATIONS)
+    encoder->encode(notificationPermissions);
+#endif
 }
 
 bool WebProcessCreationParameters::decode(CoreIPC::ArgumentDecoder* decoder, WebProcessCreationParameters& parameters)
@@ -193,6 +197,11 @@ bool WebProcessCreationParameters::decode(CoreIPC::ArgumentDecoder* decoder, Web
         return false;
 #endif
 
+#if ENABLE(NOTIFICATIONS)
+    if (!decoder->decode(parameters.notificationPermissions))
+        return false;
+#endif
+
     return true;
 }
 
index bbdaceb..3a3764d 100644 (file)
@@ -31,6 +31,7 @@
 #include "TextCheckerState.h"
 #include <wtf/RetainPtr.h>
 #include <wtf/Vector.h>
+#include <wtf/text/StringHash.h>
 #include <wtf/text/WTFString.h>
 
 #if PLATFORM(MAC)
@@ -121,6 +122,10 @@ struct WebProcessCreationParameters {
 #if PLATFORM(QT)
     String cookieStorageDirectory;
 #endif
+
+#if ENABLE(NOTIFICATIONS)
+    HashMap<String, bool> notificationPermissions;
+#endif
 };
 
 } // namespace WebKit
index 347f83e..66074c5 100644 (file)
@@ -36,7 +36,15 @@ class WebSecurityOrigin : public APIObject {
 public:
     static const Type APIType = TypeSecurityOrigin;
 
-    static PassRefPtr<WebSecurityOrigin> create(const String& identifier)
+    static PassRefPtr<WebSecurityOrigin> createFromString(const String& string)
+    {
+        RefPtr<WebCore::SecurityOrigin> securityOrigin = WebCore::SecurityOrigin::createFromString(string);
+        if (!securityOrigin)
+            return 0;
+        return adoptRef(new WebSecurityOrigin(securityOrigin.release()));
+    }
+
+    static PassRefPtr<WebSecurityOrigin> createFromDatabaseIdentifier(const String& identifier)
     {
         RefPtr<WebCore::SecurityOrigin> securityOrigin = WebCore::SecurityOrigin::createFromDatabaseIdentifier(identifier);
         if (!securityOrigin)
@@ -57,6 +65,7 @@ public:
     unsigned short port() const { return m_securityOrigin->port(); }
 
     const String databaseIdentifier() const { return m_securityOrigin->databaseIdentifier(); }
+    const String toString() const { return m_securityOrigin->toString(); }
 
 private:
     WebSecurityOrigin(PassRefPtr<WebCore::SecurityOrigin> securityOrigin)
index 6ddfa4c..60671a7 100644 (file)
@@ -55,3 +55,13 @@ void WKNotificationManagerProviderDidCloseNotifications(WKNotificationManagerRef
 {
     toImpl(managerRef)->providerDidCloseNotifications(toImpl(notificationIDs));
 }
+
+void WKNotificationManagerProviderDidUpdateNotificationPolicy(WKNotificationManagerRef managerRef, WKSecurityOriginRef origin, bool allowed)
+{
+    toImpl(managerRef)->providerDidUpdateNotificationPolicy(toImpl(origin), allowed);
+}
+
+void WKNotificationManagerProviderDidRemoveNotificationPolicies(WKNotificationManagerRef managerRef, WKArrayRef origins)
+{
+    toImpl(managerRef)->providerDidRemoveNotificationPolicies(toImpl(origins));
+}
index 7360dad..7074a21 100644 (file)
@@ -39,6 +39,8 @@ WK_EXPORT void WKNotificationManagerSetProvider(WKNotificationManagerRef manager
 WK_EXPORT void WKNotificationManagerProviderDidShowNotification(WKNotificationManagerRef managerRef, uint64_t notificationID);
 WK_EXPORT void WKNotificationManagerProviderDidClickNotification(WKNotificationManagerRef managerRef, uint64_t notificationID);
 WK_EXPORT void WKNotificationManagerProviderDidCloseNotifications(WKNotificationManagerRef managerRef, WKArrayRef notificationIDs);
+WK_EXPORT void WKNotificationManagerProviderDidUpdateNotificationPolicy(WKNotificationManagerRef managerRef, WKSecurityOriginRef origin, bool allowed);
+WK_EXPORT void WKNotificationManagerProviderDidRemoveNotificationPolicies(WKNotificationManagerRef managerRef, WKArrayRef origins);
 
 #ifdef __cplusplus
 }
index 580608c..42a4beb 100644 (file)
@@ -35,9 +35,9 @@ extern "C" {
 typedef void (*WKNotificationProviderShowCallback)(WKPageRef page, WKNotificationRef notification, const void* clientInfo);
 typedef void (*WKNotificationProviderCancelCallback)(WKNotificationRef notification, const void* clientInfo);
 typedef void (*WKNotificationProviderDidDestroyNotificationCallback)(WKNotificationRef notification, const void* clientInfo);
-typedef int (*WKNotificationProviderPolicyForNotificationPermissionAtOriginCallback)(WKSecurityOriginRef origin, const void *clientInfo);
 typedef void (*WKNotificationProviderAddNotificationManagerCallback)(WKNotificationManagerRef manager, const void* clientInfo);
 typedef void (*WKNotificationProviderRemoveNotificationManagerCallback)(WKNotificationManagerRef manager, const void* clientInfo);
+typedef WKDictionaryRef (*WKNotificationProviderNotificationPermissionsCallback)(const void* clientInfo);
 
 struct WKNotificationProvider {
     int                                                                   version;
@@ -45,9 +45,9 @@ struct WKNotificationProvider {
     WKNotificationProviderShowCallback                                    show;
     WKNotificationProviderCancelCallback                                  cancel;
     WKNotificationProviderDidDestroyNotificationCallback                  didDestroyNotification;
-    WKNotificationProviderPolicyForNotificationPermissionAtOriginCallback policyForNotificationPermissionAtOrigin;
     WKNotificationProviderAddNotificationManagerCallback                  addNotificationManager;
     WKNotificationProviderRemoveNotificationManagerCallback               removeNotificationManager;
+    WKNotificationProviderNotificationPermissionsCallback                 notificationPermissions;
 };
 typedef struct WKNotificationProvider WKNotificationProvider;
 
index 35eb5d9..1413267 100644 (file)
@@ -711,3 +711,13 @@ bool WKPreferencesGetShouldDisplayTextDescriptions(WKPreferencesRef preferencesR
 {
     return toImpl(preferencesRef)->shouldDisplayTextDescriptions();
 }
+
+void WKPreferencesSetNotificationsEnabled(WKPreferencesRef preferencesRef, bool enabled)
+{
+    toImpl(preferencesRef)->setNotificationsEnabled(enabled);
+}
+
+bool WKPreferencesGetNotificationsEnabled(WKPreferencesRef preferencesRef)
+{
+    return toImpl(preferencesRef)->notificationsEnabled();
+}
index 00fc89d..f13559a 100644 (file)
@@ -193,6 +193,10 @@ WK_EXPORT bool WKPreferencesGetShouldDisplayCaptions(WKPreferencesRef preference
 WK_EXPORT void WKPreferencesSetShouldDisplayTextDescriptions(WKPreferencesRef preferencesRef, bool enabled);
 WK_EXPORT bool WKPreferencesGetShouldDisplayTextDescriptions(WKPreferencesRef preferencesRef);
 
+// Defaults to false
+WK_EXPORT void WKPreferencesSetNotificationsEnabled(WKPreferencesRef preferencesRef, bool enabled);
+WK_EXPORT bool WKPreferencesGetNotificationsEnabled(WKPreferencesRef preferencesRef);
+
 #ifdef __cplusplus
 }
 #endif
index 7bb7443..065bbbf 100644 (file)
 
 namespace WebKit {
 
-WebNotification::WebNotification(const String& title, const String& body, const String& originIdentifier, uint64_t notificationID)
+WebNotification::WebNotification(const String& title, const String& body, const String& originString, uint64_t notificationID)
     : m_title(title)
     , m_body(body)
-    , m_origin(WebSecurityOrigin::create(originIdentifier))
+    , m_origin(WebSecurityOrigin::createFromString(originString))
     , m_notificationID(notificationID)
 {
 }
index 0b89a0a..9447da4 100644 (file)
@@ -45,9 +45,9 @@ class WebNotification : public APIObject {
 public:
     static const Type APIType = TypeNotification;
     
-    static PassRefPtr<WebNotification> create(const String& title, const String& body, const String& originIdentifier, uint64_t notificationID)
+    static PassRefPtr<WebNotification> create(const String& title, const String& body, const String& originString, uint64_t notificationID)
     {
-        return adoptRef(new WebNotification(title, body, originIdentifier, notificationID));
+        return adoptRef(new WebNotification(title, body, originString, notificationID));
     }
     
     const String& title() const { return m_title; }
@@ -57,7 +57,7 @@ public:
     uint64_t notificationID() const { return m_notificationID; }
 
 private:
-    WebNotification(const String& title, const String& body, const String& originIdentifier, uint64_t notificationID);
+    WebNotification(const String& title, const String& body, const String& originString, uint64_t notificationID);
 
     virtual Type type() const { return APIType; }
     
index 7d7c045..e74ad07 100644 (file)
@@ -27,6 +27,7 @@
 #include "WebNotificationManagerProxy.h"
 
 #include "ImmutableArray.h"
+#include "ImmutableDictionary.h"
 #include "WebContext.h"
 #include "WebNotification.h"
 #include "WebNotificationManagerMessages.h"
@@ -57,26 +58,31 @@ void WebNotificationManagerProxy::invalidate()
 void WebNotificationManagerProxy::initializeProvider(const WKNotificationProvider *provider)
 {
     m_provider.initialize(provider);
+    m_provider.addNotificationManager(this);
 }
 
-void WebNotificationManagerProxy::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
+void WebNotificationManagerProxy::populateCopyOfNotificationPermissions(HashMap<String, bool>& permissions)
 {
-    didReceiveWebNotificationManagerProxyMessage(connection, messageID, arguments);
+    RefPtr<ImmutableDictionary> knownPermissions = m_provider.notificationPermissions();
+    permissions.clear();
+    RefPtr<ImmutableArray> knownOrigins = knownPermissions->keys();
+    for (size_t i = 0; i < knownOrigins->size(); ++i) {
+        WebString* origin = knownOrigins->at<WebString>(i);
+        permissions.set(origin->string(), knownPermissions->get<WebBoolean>(origin->string())->value());
+    }
 }
 
-void WebNotificationManagerProxy::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, OwnPtr<CoreIPC::ArgumentEncoder>& reply)
+void WebNotificationManagerProxy::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
 {
-    didReceiveSyncWebNotificationManagerProxyMessage(connection, messageID, arguments, reply);
+    didReceiveWebNotificationManagerProxyMessage(connection, messageID, arguments);
 }
 
-void WebNotificationManagerProxy::show(WebPageProxy* page, const String& title, const String& body, const String& originIdentifier, uint64_t notificationID)
+void WebNotificationManagerProxy::show(WebPageProxy* page, const String& title, const String& body, const String& originString, uint64_t notificationID)
 {
     if (!isNotificationIDValid(notificationID))
         return;
     
-    m_provider.addNotificationManager(this);
-
-    RefPtr<WebNotification> notification = WebNotification::create(title, body, originIdentifier, notificationID);
+    RefPtr<WebNotification> notification = WebNotification::create(title, body, originString, notificationID);
     m_notifications.set(notificationID, notification);
     m_provider.show(page, notification.get());
 }
@@ -90,7 +96,6 @@ void WebNotificationManagerProxy::cancel(uint64_t notificationID)
     if (!notification)
         return;
 
-    m_provider.addNotificationManager(this);
     m_provider.cancel(notification.get());
 }
     
@@ -106,12 +111,6 @@ void WebNotificationManagerProxy::didDestroyNotification(uint64_t notificationID
     m_provider.didDestroyNotification(notification.get());
 }
 
-void WebNotificationManagerProxy::notificationPermissionLevel(const String& originIdentifier, uint64_t& permissionLevel)
-{
-    RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::create(originIdentifier);
-    permissionLevel = m_provider.policyForNotificationPermissionAtOrigin(origin.get());
-}
-
 void WebNotificationManagerProxy::providerDidShowNotification(uint64_t notificationID)
 {
     if (!m_context)
@@ -148,4 +147,30 @@ void WebNotificationManagerProxy::providerDidCloseNotifications(ImmutableArray*
         m_context->sendToAllProcesses(Messages::WebNotificationManager::DidCloseNotifications(vectorNotificationIDs));
 }
 
+void WebNotificationManagerProxy::providerDidUpdateNotificationPolicy(const WebSecurityOrigin* origin, bool allowed)
+{
+    if (!m_context)
+        return;
+
+    m_context->sendToAllProcesses(Messages::WebNotificationManager::DidUpdateNotificationDecision(origin->toString(), allowed));
+}
+
+void WebNotificationManagerProxy::providerDidRemoveNotificationPolicies(ImmutableArray* origins)
+{
+    if (!m_context)
+        return;
+
+    size_t size = origins->size();
+    if (!size)
+        return;
+    
+    Vector<String> originStrings;
+    originStrings.reserveInitialCapacity(size);
+    
+    for (size_t i = 0; i < size; ++i)
+        originStrings.append(origins->at<WebSecurityOrigin>(i)->toString());
+    
+    m_context->sendToAllProcesses(Messages::WebNotificationManager::DidRemoveNotificationDecisions(originStrings));
+}
+
 } // namespace WebKit
index 1705abc..8f4b9e9 100644 (file)
 #include "APIObject.h"
 #include "MessageID.h"
 #include "WebNotificationProvider.h"
+#include <WebCore/NotificationPresenter.h>
 #include <wtf/HashMap.h>
 #include <wtf/OwnPtr.h>
 #include <wtf/PassRefPtr.h>
+#include <wtf/text/StringHash.h>
 
 namespace CoreIPC {
 class ArgumentDecoder;
@@ -44,6 +46,7 @@ namespace WebKit {
 class ImmutableArray;
 class WebContext;
 class WebPageProxy;
+class WebSecurityOrigin;
 
 class WebNotificationManagerProxy : public APIObject {
 public:
@@ -55,15 +58,17 @@ public:
     void clearContext() { m_context = 0; }
 
     void initializeProvider(const WKNotificationProvider*);
+    void populateCopyOfNotificationPermissions(HashMap<String, bool>&);
 
-    void show(WebPageProxy*, const WTF::String& title, const WTF::String& body, const WTF::String& originIdentifier, uint64_t notificationID);
+    void show(WebPageProxy*, const String& title, const String& body, const String& originString, uint64_t notificationID);
 
     void providerDidShowNotification(uint64_t notificationID);
     void providerDidClickNotification(uint64_t notificationID);
     void providerDidCloseNotifications(ImmutableArray* notificationIDs);
+    void providerDidUpdateNotificationPolicy(const WebSecurityOrigin*, bool allowed);
+    void providerDidRemoveNotificationPolicies(ImmutableArray* origins);
     
     void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*);
-    void didReceiveSyncMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, OwnPtr<CoreIPC::ArgumentEncoder>&);
 
 private:
     explicit WebNotificationManagerProxy(WebContext*);
@@ -71,12 +76,10 @@ private:
     virtual Type type() const { return APIType; }
     
     void didReceiveWebNotificationManagerProxyMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*);
-    void didReceiveSyncWebNotificationManagerProxyMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, OwnPtr<CoreIPC::ArgumentEncoder>&);
     
     // Message handlers
     void cancel(uint64_t notificationID);
     void didDestroyNotification(uint64_t notificationID);
-    void notificationPermissionLevel(const WTF::String& originIdentifier, uint64_t& permissionLevel);
 
     typedef HashMap<uint64_t, RefPtr<WebNotification> > WebNotificationMap;
     
index 04d1a01..a06fd02 100644 (file)
@@ -23,6 +23,4 @@
 messages -> WebNotificationManagerProxy {
     Cancel(uint64_t notificationID);
     DidDestroyNotification(uint64_t notificationID);
-
-    NotificationPermissionLevel(WTF::String originIdentifier) -> (uint64_t policy)
 }
index 080aea6..afd13bc 100644 (file)
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "WebNotificationProvider.h"
 
+#include "ImmutableDictionary.h"
 #include "WKAPICast.h"
 #include "WebNotification.h"
 #include "WebNotificationManagerProxy.h"
@@ -57,14 +58,6 @@ void WebNotificationProvider::didDestroyNotification(WebNotification* notificati
     m_client.didDestroyNotification(toAPI(notification), m_client.clientInfo);
 }
 
-int WebNotificationProvider::policyForNotificationPermissionAtOrigin(WebSecurityOrigin* origin)
-{
-    if (!m_client.policyForNotificationPermissionAtOrigin)
-        return INT_MIN;
-    
-    return m_client.policyForNotificationPermissionAtOrigin(toAPI(origin), m_client.clientInfo);
-}
-
 void WebNotificationProvider::addNotificationManager(WebNotificationManagerProxy* manager)
 {
     if (!m_client.addNotificationManager)
@@ -81,4 +74,12 @@ void WebNotificationProvider::removeNotificationManager(WebNotificationManagerPr
     m_client.removeNotificationManager(toAPI(manager), m_client.clientInfo);
 }
 
+PassRefPtr<ImmutableDictionary> WebNotificationProvider::notificationPermissions()
+{
+    if (!m_client.notificationPermissions)
+        return ImmutableDictionary::create();
+
+    return adoptRef(toImpl(m_client.notificationPermissions(m_client.clientInfo)));
+}
+
 } // namespace WebKit
index 43d9639..8503ee2 100644 (file)
@@ -32,6 +32,7 @@
 
 namespace WebKit {
 
+class ImmutableDictionary;
 class WebNotification;
 class WebNotificationManagerProxy;
 class WebPageProxy;
@@ -42,10 +43,11 @@ public:
     void show(WebPageProxy*, WebNotification*);
     void cancel(WebNotification*);
     void didDestroyNotification(WebNotification*);
-    int policyForNotificationPermissionAtOrigin(WebSecurityOrigin*);
 
     void addNotificationManager(WebNotificationManagerProxy*);
     void removeNotificationManager(WebNotificationManagerProxy*);
+    
+    PassRefPtr<ImmutableDictionary> notificationPermissions();
 };
 
 } // namespace WebKit
index 1c3dd3b..e4d1a5c 100644 (file)
@@ -281,6 +281,10 @@ void WebContext::ensureWebProcess()
 
     parameters.defaultRequestTimeoutInterval = WebURLRequest::defaultTimeoutInterval();
 
+#if ENABLE(NOTIFICATIONS)
+    m_notificationManagerProxy->populateCopyOfNotificationPermissions(parameters.notificationPermissions);
+#endif
+
     // Add any platform specific parameters
     platformInitializeWebProcess(parameters);
 
index 26c518f..e61faa1 100644 (file)
@@ -137,7 +137,7 @@ void WebDatabaseManagerProxy::didGetDatabasesByOrigin(const Vector<OriginAndData
     for (size_t i = 0; i < originAndDatabasesCount; ++i) {
         const OriginAndDatabases& originAndDatabases = originAndDatabasesVector[i];
     
-        RefPtr<APIObject> origin = WebSecurityOrigin::create(originAndDatabases.originIdentifier);
+        RefPtr<APIObject> origin = WebSecurityOrigin::createFromDatabaseIdentifier(originAndDatabases.originIdentifier);
     
         size_t databasesCount = originAndDatabases.databases.size();
         Vector<RefPtr<APIObject> > databases(databasesCount);
@@ -188,7 +188,7 @@ void WebDatabaseManagerProxy::didGetDatabaseOrigins(const Vector<String>& origin
     Vector<RefPtr<APIObject> > securityOrigins(originIdentifiersCount);
 
     for (size_t i = 0; i < originIdentifiersCount; ++i)
-        securityOrigins[i] = WebSecurityOrigin::create(originIdentifiers[i]);
+        securityOrigins[i] = WebSecurityOrigin::createFromDatabaseIdentifier(originIdentifiers[i]);
 
     callback->performCallbackWithReturnValue(ImmutableArray::adopt(securityOrigins).get());
 }
@@ -219,13 +219,13 @@ void WebDatabaseManagerProxy::setQuotaForOrigin(WebSecurityOrigin* origin, uint6
 
 void WebDatabaseManagerProxy::didModifyOrigin(const String& originIdentifier)
 {
-    RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::create(originIdentifier);
+    RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::createFromDatabaseIdentifier(originIdentifier);
     m_client.didModifyOrigin(this, origin.get());
 }
 
 void WebDatabaseManagerProxy::didModifyDatabase(const String& originIdentifier, const String& databaseIdentifier)
 {
-    RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::create(originIdentifier);
+    RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::createFromDatabaseIdentifier(originIdentifier);
     m_client.didModifyDatabase(this, origin.get(), databaseIdentifier);
 }
 
index 1218232..52ff6c0 100644 (file)
@@ -3296,7 +3296,7 @@ void WebPageProxy::exceededDatabaseQuota(uint64_t frameID, const String& originI
     WebFrameProxy* frame = process()->webFrame(frameID);
     MESSAGE_CHECK(frame);
 
-    RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::create(originIdentifier);
+    RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::createFromDatabaseIdentifier(originIdentifier);
 
     newQuota = m_uiClient.exceededDatabaseQuota(this, frame, origin.get(), databaseName, displayName, currentQuota, currentOriginUsage, currentDatabaseUsage, expectedUsage);
 }
@@ -3306,28 +3306,29 @@ void WebPageProxy::requestGeolocationPermissionForFrame(uint64_t geolocationID,
     WebFrameProxy* frame = process()->webFrame(frameID);
     MESSAGE_CHECK(frame);
 
-    RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::create(originIdentifier);
+    // FIXME: Geolocation should probably be using toString() as its string representation instead of databaseIdentifier().
+    RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::createFromDatabaseIdentifier(originIdentifier);
     RefPtr<GeolocationPermissionRequestProxy> request = m_geolocationPermissionRequestManager.createRequest(geolocationID);
 
     if (!m_uiClient.decidePolicyForGeolocationPermissionRequest(this, frame, origin.get(), request.get()))
         request->deny();
 }
 
-void WebPageProxy::requestNotificationPermission(uint64_t requestID, const String& originIdentifier)
+void WebPageProxy::requestNotificationPermission(uint64_t requestID, const String& originString)
 {
     if (!isRequestIDValid(requestID))
         return;
 
-    RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::create(originIdentifier);
+    RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::createFromString(originString);
     RefPtr<NotificationPermissionRequest> request = m_notificationPermissionRequestManager.createRequest(requestID);
     
     if (!m_uiClient.decidePolicyForNotificationPermissionRequest(this, origin.get(), request.get()))
         request->deny();
 }
 
-void WebPageProxy::showNotification(const String& title, const String& body, const String& originIdentifier, uint64_t notificationID)
+void WebPageProxy::showNotification(const String& title, const String& body, const String& originString, uint64_t notificationID)
 {
-    m_process->context()->notificationManagerProxy()->show(this, title, body, originIdentifier, notificationID);
+    m_process->context()->notificationManagerProxy()->show(this, title, body, originString, notificationID);
 }
 
 float WebPageProxy::headerHeight(WebFrameProxy* frame)
index 2b45785..9dade1e 100644 (file)
@@ -709,8 +709,8 @@ private:
     void reattachToWebProcess();
     void reattachToWebProcessWithItem(WebBackForwardListItem*);
 
-    void requestNotificationPermission(uint64_t notificationID, const String& originIdentifier);
-    void showNotification(const String& title, const String& body, const String& originIdentifier, uint64_t notificationID);
+    void requestNotificationPermission(uint64_t notificationID, const String& originString);
+    void showNotification(const String& title, const String& body, const String& originString, uint64_t notificationID);
     
 #if USE(TILED_BACKING_STORE)
     void pageDidRequestScroll(const WebCore::IntPoint&);
index 8c99b4e..2109d9e 100644 (file)
@@ -334,11 +334,6 @@ void WebProcessProxy::didReceiveSyncMessage(CoreIPC::Connection* connection, Cor
         return;
     }
 
-    if (messageID.is<CoreIPC::MessageClassWebNotificationManagerProxy>()) {
-        m_context->notificationManagerProxy()->didReceiveSyncMessage(connection, messageID, arguments, reply);
-        return;
-    }
-
     uint64_t pageID = arguments->destinationID();
     if (!pageID)
         return;
index 3eeaa50..7d662f1 100644 (file)
 #include "WebPageProxyMessages.h"
 #include "WebProcess.h"
 #include <WebCore/Notification.h>
+#include <WebCore/Page.h>
 #include <WebCore/ScriptExecutionContext.h>
 #include <WebCore/SecurityOrigin.h>
+#include <WebCore/Settings.h>
 
 using namespace WebCore;
 
@@ -60,11 +62,14 @@ NotificationPermissionRequestManager::NotificationPermissionRequestManager(WebPa
 void NotificationPermissionRequestManager::startRequest(SecurityOrigin* origin, PassRefPtr<VoidCallback> callback)
 {
 #if ENABLE(NOTIFICATIONS)
+    if (permissionLevel(origin) != NotificationPresenter::PermissionNotAllowed)
+        return;
+
     uint64_t requestID = generateRequestID();
     m_originToIDMap.set(origin, requestID);
     m_idToOriginMap.set(requestID, origin);
     m_idToCallbackMap.set(requestID, callback);
-    m_page->send(Messages::WebPageProxy::RequestNotificationPermission(requestID, origin->databaseIdentifier()));
+    m_page->send(Messages::WebPageProxy::RequestNotificationPermission(requestID, origin->toString()));
 #else
     UNUSED_PARAM(origin);
     UNUSED_PARAM(callback);
@@ -88,11 +93,10 @@ void NotificationPermissionRequestManager::cancelRequest(SecurityOrigin* origin)
 NotificationPresenter::Permission NotificationPermissionRequestManager::permissionLevel(SecurityOrigin* securityOrigin)
 {
 #if ENABLE(NOTIFICATIONS)
-    uint64_t permissionLevel;
-    WebProcess::shared().connection()->sendSync(Messages::WebNotificationManagerProxy::NotificationPermissionLevel(securityOrigin->databaseIdentifier()),
-                                                Messages::WebNotificationManagerProxy::NotificationPermissionLevel::Reply(permissionLevel),
-                                                0);
-    return static_cast<NotificationPresenter::Permission>(permissionLevel);
+    if (!m_page->corePage()->settings()->notificationsEnabled())
+        return NotificationPresenter::PermissionDenied;
+    
+    return WebProcess::shared().notificationManager().policyForOrigin(securityOrigin);
 #else
     UNUSED_PARAM(securityOrigin);
     return NotificationPresenter::PermissionDenied;
index dfc30f5..e7f0c15 100644 (file)
 #include "WebNotificationManagerProxyMessages.h"
 #include "WebPageProxyMessages.h"
 #include <WebCore/Notification.h>
+#include <WebCore/Page.h>
 #include <WebCore/ScriptExecutionContext.h>
 #include <WebCore/SecurityOrigin.h>
+#include <WebCore/Settings.h>
 #endif
 
 using namespace WebCore;
@@ -64,17 +66,46 @@ void WebNotificationManager::didReceiveMessage(CoreIPC::Connection* connection,
     didReceiveWebNotificationManagerMessage(connection, messageID, arguments);
 }
 
+void WebNotificationManager::initialize(const HashMap<String, bool>& permissions)
+{
+    m_permissionsMap = permissions;
+}
+
+void WebNotificationManager::didUpdateNotificationDecision(const String& originString, bool allowed)
+{
+    m_permissionsMap.set(originString, allowed);
+}
+
+void WebNotificationManager::didRemoveNotificationDecisions(const Vector<String>& originStrings)
+{
+    size_t count = originStrings.size();
+    for (size_t i = 0; i < count; ++i)
+        m_permissionsMap.remove(originStrings[i]);
+}
+
+NotificationPresenter::Permission WebNotificationManager::policyForOrigin(WebCore::SecurityOrigin *origin) const
+{
+    if (!origin)
+        return NotificationPresenter::PermissionNotAllowed;
+    
+    HashMap<String, bool>::const_iterator it = m_permissionsMap.find(origin->toString());
+    if (it != m_permissionsMap.end())
+        return it->second ? NotificationPresenter::PermissionAllowed : NotificationPresenter::PermissionDenied;
+    
+    return NotificationPresenter::PermissionNotAllowed;
+}
+
 bool WebNotificationManager::show(Notification* notification, WebPage* page)
 {
 #if ENABLE(NOTIFICATIONS)
-    if (!notification)
+    if (!notification || !page->corePage()->settings()->notificationsEnabled())
         return true;
     
     uint64_t notificationID = generateNotificationID();
     m_notificationMap.set(notification, notificationID);
     m_notificationIDMap.set(notificationID, notification);
     
-    m_process->connection()->send(Messages::WebPageProxy::ShowNotification(notification->contents().title, notification->contents().body, notification->scriptExecutionContext()->securityOrigin()->databaseIdentifier(), notificationID), page->pageID());
+    m_process->connection()->send(Messages::WebPageProxy::ShowNotification(notification->contents().title, notification->contents().body, notification->scriptExecutionContext()->securityOrigin()->toString(), notificationID), page->pageID());
 #endif
     return true;
 }
@@ -82,7 +113,7 @@ bool WebNotificationManager::show(Notification* notification, WebPage* page)
 void WebNotificationManager::cancel(Notification* notification, WebPage* page)
 {
 #if ENABLE(NOTIFICATIONS)
-    if (!notification)
+    if (!notification || !page->corePage()->settings()->notificationsEnabled())
         return;
     
     uint64_t notificationID = m_notificationMap.get(notification);
index 3b32f0a..6150739 100644 (file)
 #define WebNotificationManager_h
 
 #include "MessageID.h"
+#include <WebCore/NotificationPresenter.h>
 #include <wtf/HashMap.h>
 #include <wtf/Noncopyable.h>
 #include <wtf/RefPtr.h>
 #include <wtf/Vector.h>
+#include <wtf/text/StringHash.h>
 
 namespace CoreIPC {
 class ArgumentDecoder;
@@ -39,6 +41,7 @@ class Connection;
 
 namespace WebCore {
 class Notification;
+class SecurityOrigin;
 }
 
 namespace WebKit {
@@ -52,12 +55,17 @@ public:
     explicit WebNotificationManager(WebProcess*);
     ~WebNotificationManager();
 
+    void initialize(const HashMap<String, bool>& permissions);
+    
     bool show(WebCore::Notification*, WebPage*);
     void cancel(WebCore::Notification*, WebPage*);
     // This callback comes from WebCore, not messaged from the UI process.
     void didDestroyNotification(WebCore::Notification*, WebPage*);
 
     void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*);
+    
+    // Looks in local cache for permission. If not found, returns DefaultDenied.
+    WebCore::NotificationPresenter::Permission policyForOrigin(WebCore::SecurityOrigin*) const;
 
 private:
     // Implemented in generated WebNotificationManagerMessageReceiver.cpp
@@ -66,6 +74,8 @@ private:
     void didShowNotification(uint64_t notificationID);
     void didClickNotification(uint64_t notificationID);
     void didCloseNotifications(const Vector<uint64_t>& notificationIDs);
+    void didUpdateNotificationDecision(const String& originString, bool allowed);
+    void didRemoveNotificationDecisions(const Vector<String>& originStrings);
 
     WebProcess* m_process;
 
@@ -75,6 +85,8 @@ private:
     
     typedef HashMap<uint64_t, RefPtr<WebCore::Notification> > NotificationIDMap;
     NotificationIDMap m_notificationIDMap;
+    
+    HashMap<String, bool> m_permissionsMap;
 #endif
 };
 
index 13d97ff..b88f26c 100644 (file)
@@ -24,4 +24,6 @@ messages -> WebNotificationManager {
     DidShowNotification(uint64_t notificationID);
     DidClickNotification(uint64_t notificationID);
     DidCloseNotifications(Vector<uint64_t> notificationIDs);
+    DidUpdateNotificationDecision(WTF::String originString, bool allowed);
+    DidRemoveNotificationDecisions(Vector<WTF::String> originStrings);
 }
index a1c3c2c..365d578 100644 (file)
@@ -1878,6 +1878,10 @@ void WebPage::updatePreferences(const WebPreferencesStore& store)
     settings->setShouldDisplayTextDescriptions(store.getBoolValueForKey(WebPreferencesKey::shouldDisplayTextDescriptionsKey()));
 #endif
 
+#if ENABLE(NOTIFICATIONS)
+    settings->setNotificationsEnabled(store.getBoolValueForKey(WebPreferencesKey::notificationsEnabledKey()));
+#endif
+
     platformPreferencesDidChange(store);
 }
 
index 7d67e1e..c932ef3 100644 (file)
@@ -252,6 +252,8 @@ void WebProcess::platformInitializeWebProcess(const WebProcessCreationParameters
     WebInspector::setLocalizedStringsPath(parameters.webInspectorLocalizedStringsPath);
 
     m_compositingRenderServerPort = parameters.acceleratedCompositingPort.port();
+    
+    m_notificationManager.initialize(parameters.notificationPermissions);
 
     // rdar://9118639 accessibilityFocusedUIElement in NSApplication defaults to use the keyWindow. Since there's
     // no window in WK2, NSApplication needs to use the focused page's focused element.