<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[183365] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/183365">183365</a></dd>
<dt>Author</dt> <dd>darin@apple.com</dd>
<dt>Date</dt> <dd>2015-04-26 14:18:15 -0700 (Sun, 26 Apr 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>REGRESSION (<a href="http://trac.webkit.org/projects/webkit/changeset/173801">r173801</a>): Use after free in WebCore::NotificationCenter::~NotificationCenter
https://bugs.webkit.org/show_bug.cgi?id=137163

Reviewed by Andy Estes.

Source/WebCore:

Test: fast/notifications/request-notification-permission-while-reloading.html

The test doesn't crash under WebKit2, but that's still OK for our purposes.

* Modules/notifications/NotificationCenter.cpp:
(WebCore::NotificationCenter::NotificationCenter): Initialize m_timer.
(WebCore::NotificationCenter::createNotification): Moved here from the header.
(WebCore::NotificationCenter::requestPermission): Start the timer and ref the notification
center when we need to defer a callback. Also use a lambda for the callback and changed
the argument to match what the bindings actually pass. Before we said PassRefPtr, but the
bindings were not transferring ownership of the VoidCallback. The new type is a little
strange but it's consistent with how the bindings work right now.
(WebCore::NotificationCenter::timerFired): Added. Calls all the callbacks, then does a deref
to match the ref we did above.
(WebCore::NotificationCenter::requestTimedOut): Deleted.
(WebCore::NotificationCenter::NotificationRequestCallback::createAndStartTimer): Deleted.
(WebCore::NotificationCenter::NotificationRequestCallback::NotificationRequestCallback): Deleted.
(WebCore::NotificationCenter::NotificationRequestCallback::startTimer): Deleted.
(WebCore::NotificationCenter::NotificationRequestCallback::timerFired): Deleted.

* Modules/notifications/NotificationCenter.h: Reorganized the header to be a bit more tidy.
Changed the argument type for requestPermission to match the reality of what's passed by the
bindings. Removed NotificationRequestCallback and replaced the m_callbacks HashSet with a
vector of std::function.

LayoutTests:

* fast/notifications/request-notification-permission-while-reloading-expected.txt: Added.
* fast/notifications/request-notification-permission-while-reloading.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModulesnotificationsNotificationCentercpp">trunk/Source/WebCore/Modules/notifications/NotificationCenter.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesnotificationsNotificationCenterh">trunk/Source/WebCore/Modules/notifications/NotificationCenter.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastnotificationsrequestnotificationpermissionwhilereloadingexpectedtxt">trunk/LayoutTests/fast/notifications/request-notification-permission-while-reloading-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastnotificationsrequestnotificationpermissionwhilereloadinghtml">trunk/LayoutTests/fast/notifications/request-notification-permission-while-reloading.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (183364 => 183365)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-04-26 20:38:20 UTC (rev 183364)
+++ trunk/LayoutTests/ChangeLog        2015-04-26 21:18:15 UTC (rev 183365)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2015-04-26  Darin Adler  &lt;darin@apple.com&gt;
+
+        REGRESSION (r173801): Use after free in WebCore::NotificationCenter::~NotificationCenter
+        https://bugs.webkit.org/show_bug.cgi?id=137163
+
+        Reviewed by Andy Estes.
+
+        * fast/notifications/request-notification-permission-while-reloading-expected.txt: Added.
+        * fast/notifications/request-notification-permission-while-reloading.html: Added.
+
</ins><span class="cx"> 2015-04-26  Benjamin Poulain  &lt;benjamin@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         [JSC] Implement Math.clz32(), remove Number.clz()
</span></span></pre></div>
<a id="trunkLayoutTestsfastnotificationsrequestnotificationpermissionwhilereloadingexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/notifications/request-notification-permission-while-reloading-expected.txt (0 => 183365)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/notifications/request-notification-permission-while-reloading-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/notifications/request-notification-permission-while-reloading-expected.txt        2015-04-26 21:18:15 UTC (rev 183365)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+This tests that notification permission requests during page reload do not cause a crash.
+
+PASS: Test passed if we saw no crash.
</ins><span class="cx">Property changes on: trunk/LayoutTests/fast/notifications/request-notification-permission-while-reloading-expected.txt
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkLayoutTestsfastnotificationsrequestnotificationpermissionwhilereloadinghtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/notifications/request-notification-permission-while-reloading.html (0 => 183365)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/notifications/request-notification-permission-while-reloading.html                                (rev 0)
+++ trunk/LayoutTests/fast/notifications/request-notification-permission-while-reloading.html        2015-04-26 21:18:15 UTC (rev 183365)
</span><span class="lines">@@ -0,0 +1,27 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;body&gt;
+&lt;p&gt;This tests that notification permission requests during page reload do not cause a crash.&lt;/p&gt;
+&lt;p id=&quot;message&quot;&gt;FAIL: Test did not run to completion yet.&lt;/p&gt;
+&lt;script&gt;
+
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+}
+
+var tries = location.hash.substring(1) &gt;&gt;&gt; 0;
+if (tries &lt; 10) {
+    location.hash = &quot;#&quot; + (tries + 1);
+    location.reload();
+
+    setTimeout(function() {
+        webkitNotifications.requestPermission();
+    }, 0);
+} else {
+    document.getElementById(&quot;message&quot;).textContent = &quot;PASS: Test passed if we saw no crash.&quot;;
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+&lt;/script&gt;
+&lt;/body&gt;
</ins><span class="cx">Property changes on: trunk/LayoutTests/fast/notifications/request-notification-permission-while-reloading.html
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (183364 => 183365)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-04-26 20:38:20 UTC (rev 183364)
+++ trunk/Source/WebCore/ChangeLog        2015-04-26 21:18:15 UTC (rev 183365)
</span><span class="lines">@@ -1,3 +1,35 @@
</span><ins>+2015-04-26  Darin Adler  &lt;darin@apple.com&gt;
+
+        REGRESSION (r173801): Use after free in WebCore::NotificationCenter::~NotificationCenter
+        https://bugs.webkit.org/show_bug.cgi?id=137163
+
+        Reviewed by Andy Estes.
+
+        Test: fast/notifications/request-notification-permission-while-reloading.html
+
+        The test doesn't crash under WebKit2, but that's still OK for our purposes.
+
+        * Modules/notifications/NotificationCenter.cpp:
+        (WebCore::NotificationCenter::NotificationCenter): Initialize m_timer.
+        (WebCore::NotificationCenter::createNotification): Moved here from the header.
+        (WebCore::NotificationCenter::requestPermission): Start the timer and ref the notification
+        center when we need to defer a callback. Also use a lambda for the callback and changed
+        the argument to match what the bindings actually pass. Before we said PassRefPtr, but the
+        bindings were not transferring ownership of the VoidCallback. The new type is a little
+        strange but it's consistent with how the bindings work right now.
+        (WebCore::NotificationCenter::timerFired): Added. Calls all the callbacks, then does a deref
+        to match the ref we did above.
+        (WebCore::NotificationCenter::requestTimedOut): Deleted.
+        (WebCore::NotificationCenter::NotificationRequestCallback::createAndStartTimer): Deleted.
+        (WebCore::NotificationCenter::NotificationRequestCallback::NotificationRequestCallback): Deleted.
+        (WebCore::NotificationCenter::NotificationRequestCallback::startTimer): Deleted.
+        (WebCore::NotificationCenter::NotificationRequestCallback::timerFired): Deleted.
+
+        * Modules/notifications/NotificationCenter.h: Reorganized the header to be a bit more tidy.
+        Changed the argument type for requestPermission to match the reality of what's passed by the
+        bindings. Removed NotificationRequestCallback and replaced the m_callbacks HashSet with a
+        vector of std::function.
+
</ins><span class="cx"> 2015-04-26  Simon Fraser  &lt;simon.fraser@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Modernize animations code
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesnotificationsNotificationCentercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/notifications/NotificationCenter.cpp (183364 => 183365)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/notifications/NotificationCenter.cpp        2015-04-26 20:38:20 UTC (rev 183364)
+++ trunk/Source/WebCore/Modules/notifications/NotificationCenter.cpp        2015-04-26 21:18:15 UTC (rev 183365)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2009 Google Inc. All rights reserved.
</span><del>- * Copyright (C) 2012 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012, 2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions are
</span><span class="lines">@@ -35,30 +35,40 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;NotificationCenter.h&quot;
</span><span class="cx"> 
</span><del>-#include &quot;Document.h&quot;
-#include &quot;NotificationClient.h&quot;
</del><ins>+#include &quot;Notification.h&quot;
+#include &quot;ScriptExecutionContext.h&quot;
</ins><span class="cx"> #include &quot;SecurityOrigin.h&quot;
</span><del>-#include &quot;WorkerGlobalScope.h&quot;
</del><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> Ref&lt;NotificationCenter&gt; NotificationCenter::create(ScriptExecutionContext* context, NotificationClient* client)
</span><span class="cx"> {
</span><span class="cx">     auto notificationCenter = adoptRef(*new NotificationCenter(context, client));
</span><del>-    notificationCenter.get().suspendIfNeeded();
</del><ins>+    notificationCenter-&gt;suspendIfNeeded();
</ins><span class="cx">     return notificationCenter;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> NotificationCenter::NotificationCenter(ScriptExecutionContext* context, NotificationClient* client)
</span><span class="cx">     : ActiveDOMObject(context)
</span><span class="cx">     , m_client(client)
</span><ins>+    , m_timer([this]() { timerFired(); })
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(LEGACY_NOTIFICATIONS)
</span><ins>+
+RefPtr&lt;Notification&gt; NotificationCenter::createNotification(const String&amp; iconURI, const String&amp; title, const String&amp; body, ExceptionCode&amp; ec)
+{
+    if (!m_client) {
+        ec = INVALID_STATE_ERR;
+        return nullptr;
+    }
+    return Notification::create(title, body, iconURI, scriptExecutionContext(), ec, this);
+}
+
</ins><span class="cx"> int NotificationCenter::checkPermission()
</span><span class="cx"> {
</span><del>-    if (!client() || !scriptExecutionContext())
</del><ins>+    if (!m_client || !scriptExecutionContext())
</ins><span class="cx">         return NotificationClient::PermissionDenied;
</span><span class="cx"> 
</span><span class="cx">     switch (scriptExecutionContext()-&gt;securityOrigin()-&gt;canShowNotifications()) {
</span><span class="lines">@@ -73,27 +83,33 @@
</span><span class="cx">     ASSERT_NOT_REACHED();
</span><span class="cx">     return m_client-&gt;checkPermission(scriptExecutionContext());
</span><span class="cx"> }
</span><del>-#endif
</del><span class="cx"> 
</span><del>-#if ENABLE(LEGACY_NOTIFICATIONS)
-void NotificationCenter::requestPermission(PassRefPtr&lt;VoidCallback&gt; callback)
</del><ins>+void NotificationCenter::requestPermission(const RefPtr&lt;VoidCallback&gt;&amp; callback)
</ins><span class="cx"> {
</span><del>-    if (!client() || !scriptExecutionContext())
</del><ins>+    if (!m_client || !scriptExecutionContext())
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     switch (scriptExecutionContext()-&gt;securityOrigin()-&gt;canShowNotifications()) {
</span><span class="cx">     case SecurityOrigin::AlwaysAllow:
</span><del>-    case SecurityOrigin::AlwaysDeny: {
-        m_callbacks.add(NotificationRequestCallback::createAndStartTimer(this, callback));
</del><ins>+    case SecurityOrigin::AlwaysDeny:
+        if (m_callbacks.isEmpty()) {
+            ref(); // Balanced by the derefs in NotificationCenter::stop and NotificationCenter::timerFired.
+            m_timer.startOneShot(0);
+        }
+        m_callbacks.append([callback]() {
+            if (callback)
+                callback-&gt;handleEvent();
+        });
</ins><span class="cx">         return;
</span><del>-    }
</del><span class="cx">     case SecurityOrigin::Ask:
</span><del>-        return m_client-&gt;requestPermission(scriptExecutionContext(), callback);
</del><ins>+        m_client-&gt;requestPermission(scriptExecutionContext(), callback.get());
+        return;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     ASSERT_NOT_REACHED();
</span><del>-    m_client-&gt;requestPermission(scriptExecutionContext(), callback);
</del><ins>+    m_client-&gt;requestPermission(scriptExecutionContext(), callback.get());
</ins><span class="cx"> }
</span><ins>+
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> void NotificationCenter::stop()
</span><span class="lines">@@ -101,15 +117,19 @@
</span><span class="cx">     if (!m_client)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    // Clear m_client now because the call to NotificationClient::clearNotifications() below potentially
-    // destroy the NotificationCenter. This is because the notifications will be destroyed and unref the
-    // NotificationCenter.
-    auto&amp; client = *m_client;
-    m_client = nullptr;
</del><ins>+    // Clear m_client immediately to guarantee reentrant calls to NotificationCenter do nothing.
+    // Also protect |this| so it's not indirectly destroyed under us by work done by the client.
+    auto&amp; client = *std::exchange(m_client, nullptr);
+    Ref&lt;NotificationCenter&gt; protector(*this);
</ins><span class="cx"> 
</span><ins>+    if (!m_callbacks.isEmpty())
+        deref(); // Balanced by the ref in NotificationCenter::requestPermission.
+
+    m_timer.stop();
+    m_callbacks.clear();
+
</ins><span class="cx">     client.cancelRequestsForPermission(scriptExecutionContext());
</span><span class="cx">     client.clearNotifications(scriptExecutionContext());
</span><del>-    // Do not attempt the access |this|, the NotificationCenter may be destroyed at this point.
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> const char* NotificationCenter::activeDOMObjectName() const
</span><span class="lines">@@ -120,42 +140,19 @@
</span><span class="cx"> bool NotificationCenter::canSuspendForPageCache() const
</span><span class="cx"> {
</span><span class="cx">     // We don't need to worry about Notifications because those are ActiveDOMObject too.
</span><del>-    // The NotificationCenter can safely be suspended if there are no pending permission
-    // requests.
</del><ins>+    // The NotificationCenter can safely be suspended if there are no pending permission requests.
</ins><span class="cx">     return m_callbacks.isEmpty() &amp;&amp; (!m_client || !m_client-&gt;hasPendingPermissionRequests(scriptExecutionContext()));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void NotificationCenter::requestTimedOut(NotificationCenter::NotificationRequestCallback* request)
</del><ins>+void NotificationCenter::timerFired()
</ins><span class="cx"> {
</span><del>-    m_callbacks.remove(request);
</del><ins>+    ASSERT(m_client);
+    auto callbacks = WTF::move(m_callbacks);
+    for (auto&amp; callback : callbacks)
+        callback();
+    deref(); // Balanced by the ref in NotificationCenter::requestPermission.
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-PassRefPtr&lt;NotificationCenter::NotificationRequestCallback&gt; NotificationCenter::NotificationRequestCallback::createAndStartTimer(NotificationCenter* center, PassRefPtr&lt;VoidCallback&gt; callback)
-{
-    RefPtr&lt;NotificationCenter::NotificationRequestCallback&gt; requestCallback = adoptRef(new NotificationCenter::NotificationRequestCallback(center, callback));
-    requestCallback-&gt;startTimer();
-    return requestCallback.release();
-}
-
-NotificationCenter::NotificationRequestCallback::NotificationRequestCallback(NotificationCenter* center, PassRefPtr&lt;VoidCallback&gt; callback)
-    : m_notificationCenter(center)
-    , m_timer(*this, &amp;NotificationCenter::NotificationRequestCallback::timerFired)
-    , m_callback(callback)
-{
-}
-
-void NotificationCenter::NotificationRequestCallback::startTimer()
-{
-    m_timer.startOneShot(0);
-}
-
-void NotificationCenter::NotificationRequestCallback::timerFired()
-{
-    if (m_callback)
-        m_callback-&gt;handleEvent();
-    m_notificationCenter-&gt;requestTimedOut(this);
-}
-
</del><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesnotificationsNotificationCenterh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/notifications/NotificationCenter.h (183364 => 183365)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/notifications/NotificationCenter.h        2015-04-26 20:38:20 UTC (rev 183364)
+++ trunk/Source/WebCore/Modules/notifications/NotificationCenter.h        2015-04-26 21:18:15 UTC (rev 183365)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2009 Google Inc. All rights reserved.
</span><del>- * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011, 2012, 2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions are
</span><span class="lines">@@ -32,69 +32,46 @@
</span><span class="cx"> #ifndef NotificationCenter_h
</span><span class="cx"> #define NotificationCenter_h
</span><span class="cx"> 
</span><ins>+#include &quot;ActiveDOMObject.h&quot;
</ins><span class="cx"> #include &quot;ExceptionCode.h&quot;
</span><del>-#include &quot;Notification.h&quot;
-#include &quot;ScriptExecutionContext.h&quot;
</del><span class="cx"> #include &quot;Timer.h&quot;
</span><del>-#include &quot;VoidCallback.h&quot;
-#include &lt;wtf/PassRefPtr.h&gt;
</del><span class="cx"> #include &lt;wtf/RefCounted.h&gt;
</span><del>-#include &lt;wtf/RefPtr.h&gt;
</del><span class="cx"> 
</span><span class="cx"> #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><ins>+class Notification;
</ins><span class="cx"> class NotificationClient;
</span><span class="cx"> class VoidCallback;
</span><span class="cx"> 
</span><del>-class NotificationCenter : public RefCounted&lt;NotificationCenter&gt;, public ActiveDOMObject {
</del><ins>+class NotificationCenter : public RefCounted&lt;NotificationCenter&gt;, private ActiveDOMObject {
</ins><span class="cx"> public:
</span><span class="cx">     static Ref&lt;NotificationCenter&gt; create(ScriptExecutionContext*, NotificationClient*);
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(LEGACY_NOTIFICATIONS)
</span><del>-    PassRefPtr&lt;Notification&gt; createNotification(const String&amp; iconURI, const String&amp; title, const String&amp; body, ExceptionCode&amp; ec)
-    {
-        if (!client()) {
-            ec = INVALID_STATE_ERR;
-            return 0;
-        }
-        return Notification::create(title, body, iconURI, scriptExecutionContext(), ec, this);
-    }
</del><ins>+    RefPtr&lt;Notification&gt; createNotification(const String&amp; iconURI, const String&amp; title, const String&amp; body, ExceptionCode&amp;);
+
+    int checkPermission();
+    void requestPermission(const RefPtr&lt;VoidCallback&gt;&amp;);
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     NotificationClient* client() const { return m_client; }
</span><span class="cx"> 
</span><del>-#if ENABLE(LEGACY_NOTIFICATIONS)
-    int checkPermission();
-    void requestPermission(PassRefPtr&lt;VoidCallback&gt; = 0);
-#endif
</del><ins>+    using ActiveDOMObject::hasPendingActivity;
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     NotificationCenter(ScriptExecutionContext*, NotificationClient*);
</span><span class="cx"> 
</span><del>-    // ActiveDOMObject API.
</del><span class="cx">     void stop() override;
</span><span class="cx">     const char* activeDOMObjectName() const override;
</span><span class="cx">     bool canSuspendForPageCache() const override;
</span><span class="cx"> 
</span><del>-    class NotificationRequestCallback : public RefCounted&lt;NotificationRequestCallback&gt; {
-    public:
-        static PassRefPtr&lt;NotificationRequestCallback&gt; createAndStartTimer(NotificationCenter*, PassRefPtr&lt;VoidCallback&gt;);
-        void startTimer();
-        void timerFired();
-    private:
-        NotificationRequestCallback(NotificationCenter*, PassRefPtr&lt;VoidCallback&gt;);
</del><ins>+    void timerFired();
</ins><span class="cx"> 
</span><del>-        RefPtr&lt;NotificationCenter&gt; m_notificationCenter;
-        Timer m_timer;
-        RefPtr&lt;VoidCallback&gt; m_callback;
-    };
-
-    void requestTimedOut(NotificationRequestCallback*);
-
</del><span class="cx">     NotificationClient* m_client;
</span><del>-    HashSet&lt;RefPtr&lt;NotificationRequestCallback&gt;&gt; m_callbacks;
</del><ins>+    Vector&lt;std::function&lt;void ()&gt;&gt; m_callbacks;
+    Timer m_timer;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre>
</div>
</div>

</body>
</html>