Index: content/browser/notifications/notification_message_filter.cc |
diff --git a/content/browser/notifications/notification_message_filter.cc b/content/browser/notifications/notification_message_filter.cc |
index f1aa17a60ab9ba7fcafbeab5f55b480cc0f109cc..200dff03e6bb6e33c70b214177b84893d168b219 100644 |
--- a/content/browser/notifications/notification_message_filter.cc |
+++ b/content/browser/notifications/notification_message_filter.cc |
@@ -12,6 +12,7 @@ |
#include "content/public/browser/browser_thread.h" |
#include "content/public/browser/content_browser_client.h" |
#include "content/public/browser/desktop_notification_delegate.h" |
+#include "content/public/browser/notification_database_data.h" |
#include "content/public/browser/platform_notification_service.h" |
#include "content/public/browser/render_process_host.h" |
#include "content/public/common/content_client.h" |
@@ -27,14 +28,21 @@ NotificationMessageFilter::NotificationMessageFilter( |
process_id_(process_id), |
notification_context_(notification_context), |
resource_context_(resource_context), |
- browser_context_(browser_context) {} |
+ browser_context_(browser_context), |
+ weak_factory_io_(this) {} |
NotificationMessageFilter::~NotificationMessageFilter() {} |
void NotificationMessageFilter::DidCloseNotification(int notification_id) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::UI); |
+ |
close_closures_.erase(notification_id); |
} |
+void NotificationMessageFilter::OnDestruct() const { |
+ BrowserThread::DeleteOnIOThread::Destruct(this); |
+} |
+ |
bool NotificationMessageFilter::OnMessageReceived(const IPC::Message& message) { |
bool handled = true; |
IPC_BEGIN_MESSAGE_MAP(NotificationMessageFilter, message) |
@@ -59,24 +67,15 @@ bool NotificationMessageFilter::OnMessageReceived(const IPC::Message& message) { |
void NotificationMessageFilter::OverrideThreadForMessage( |
const IPC::Message& message, content::BrowserThread::ID* thread) { |
if (message.type() == PlatformNotificationHostMsg_Show::ID || |
- message.type() == PlatformNotificationHostMsg_ShowPersistent::ID || |
- message.type() == PlatformNotificationHostMsg_Close::ID || |
- message.type() == PlatformNotificationHostMsg_ClosePersistent::ID) |
+ message.type() == PlatformNotificationHostMsg_Close::ID) |
*thread = BrowserThread::UI; |
} |
void NotificationMessageFilter::OnCheckNotificationPermission( |
const GURL& origin, blink::WebNotificationPermission* permission) { |
DCHECK_CURRENTLY_ON(BrowserThread::IO); |
- PlatformNotificationService* service = |
- GetContentClient()->browser()->GetPlatformNotificationService(); |
- if (service) { |
- *permission = service->CheckPermissionOnIOThread(resource_context_, |
- origin, |
- process_id_); |
- } else { |
- *permission = blink::WebNotificationPermissionDenied; |
- } |
+ |
+ *permission = GetPermissionForOriginOnIO(origin); |
} |
void NotificationMessageFilter::OnShowPlatformNotification( |
@@ -116,25 +115,58 @@ void NotificationMessageFilter::OnShowPersistentNotification( |
const GURL& origin, |
const SkBitmap& icon, |
const PlatformNotificationData& notification_data) { |
- DCHECK_CURRENTLY_ON(BrowserThread::UI); |
- if (!RenderProcessHost::FromID(process_id_)) |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ if (GetPermissionForOriginOnIO(origin) != |
+ blink::WebNotificationPermissionAllowed) { |
+ BadMessageReceived(); |
return; |
+ } |
- PlatformNotificationService* service = |
- GetContentClient()->browser()->GetPlatformNotificationService(); |
- DCHECK(service); |
+ NotificationDatabaseData database_data; |
+ database_data.origin = origin; |
+ database_data.service_worker_registration_id = service_worker_registration_id; |
+ database_data.notification_data = notification_data; |
+ |
+ // TODO(peter): Significantly reduce the amount of information we need to |
+ // retain outside of the database for displaying notifications. |
+ notification_context_->WriteNotificationData( |
+ origin, |
+ database_data, |
+ base::Bind(&NotificationMessageFilter::DidWritePersistentNotificationData, |
+ weak_factory_io_.GetWeakPtr(), |
+ request_id, |
+ origin, |
+ icon, |
+ notification_data)); |
+} |
- if (!VerifyNotificationPermissionGranted(service, origin)) |
- return; |
+void NotificationMessageFilter::DidWritePersistentNotificationData( |
+ int request_id, |
+ const GURL& origin, |
+ const SkBitmap& icon, |
+ const PlatformNotificationData& notification_data, |
+ bool success, |
+ int64_t persistent_notification_id) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
- service->DisplayPersistentNotification(browser_context_, |
- service_worker_registration_id, origin, |
- icon, notification_data); |
+ if (success) { |
+ PlatformNotificationService* service = |
+ GetContentClient()->browser()->GetPlatformNotificationService(); |
+ DCHECK(service); |
+ |
+ BrowserThread::PostTask( |
+ BrowserThread::UI, |
+ FROM_HERE, |
+ base::Bind(&PlatformNotificationService::DisplayPersistentNotification, |
+ base::Unretained(service), // The service is a singleton. |
+ browser_context_, |
+ persistent_notification_id, |
+ origin, |
+ icon, |
+ notification_data)); |
+ } |
- // TODO(peter): Confirm display of the persistent notification after the |
- // data has been stored using the |notification_context_|. |
- Send(new PlatformNotificationMsg_DidShowPersistent(request_id, |
- true /* success */)); |
+ Send(new PlatformNotificationMsg_DidShowPersistent(request_id, success)); |
} |
void NotificationMessageFilter::OnGetNotifications( |
@@ -168,27 +200,68 @@ void NotificationMessageFilter::OnClosePlatformNotification( |
void NotificationMessageFilter::OnClosePersistentNotification( |
const GURL& origin, |
- const std::string& persistent_notification_id) { |
- DCHECK_CURRENTLY_ON(BrowserThread::UI); |
- if (!RenderProcessHost::FromID(process_id_)) |
+ int64_t persistent_notification_id) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ if (GetPermissionForOriginOnIO(origin) != |
+ blink::WebNotificationPermissionAllowed) { |
+ BadMessageReceived(); |
return; |
+ } |
PlatformNotificationService* service = |
GetContentClient()->browser()->GetPlatformNotificationService(); |
DCHECK(service); |
- // TODO(peter): Use |service_worker_registration_id| and |origin| when feeding |
- // the close event through the notification database. |
+ // There's no point in waiting until the database data has been removed before |
+ // closing the notification presented to the user. Post that task immediately. |
+ BrowserThread::PostTask( |
+ BrowserThread::UI, |
+ FROM_HERE, |
+ base::Bind(&PlatformNotificationService::ClosePersistentNotification, |
+ base::Unretained(service), // The service is a singleton. |
+ browser_context_, |
+ persistent_notification_id)); |
+ |
+ notification_context_->DeleteNotificationData( |
+ persistent_notification_id, |
+ origin, |
+ base::Bind(&NotificationMessageFilter:: |
+ DidDeletePersistentNotificationData, |
+ weak_factory_io_.GetWeakPtr())); |
+} |
+ |
+void NotificationMessageFilter::DidDeletePersistentNotificationData( |
+ bool success) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ // TODO(peter): Consider feeding back to the renderer that the notification |
+ // has been closed. |
+} |
+ |
+blink::WebNotificationPermission |
+NotificationMessageFilter::GetPermissionForOriginOnIO( |
+ const GURL& origin) const { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ |
+ PlatformNotificationService* service = |
+ GetContentClient()->browser()->GetPlatformNotificationService(); |
+ if (!service) |
+ return blink::WebNotificationPermissionDenied; |
- service->ClosePersistentNotification(browser_context_, |
- persistent_notification_id); |
+ return service->CheckPermissionOnIOThread(resource_context_, |
+ origin, |
+ process_id_); |
} |
bool NotificationMessageFilter::VerifyNotificationPermissionGranted( |
PlatformNotificationService* service, |
const GURL& origin) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::UI); |
+ |
blink::WebNotificationPermission permission = |
- service->CheckPermissionOnUIThread(browser_context_, origin, process_id_); |
+ service->CheckPermissionOnUIThread(browser_context_, |
+ origin, |
+ process_id_); |
+ |
if (permission == blink::WebNotificationPermissionAllowed) |
return true; |