summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/push_messaging/push_messaging_service_impl.cc128
-rw-r--r--chrome/browser/push_messaging/push_messaging_service_impl.h48
-rw-r--r--content/browser/notifications/platform_notification_context_impl.h8
-rw-r--r--content/public/browser/platform_notification_context.h9
4 files changed, 160 insertions, 33 deletions
diff --git a/chrome/browser/push_messaging/push_messaging_service_impl.cc b/chrome/browser/push_messaging/push_messaging_service_impl.cc
index ea47be0..68ec65f 100644
--- a/chrome/browser/push_messaging/push_messaging_service_impl.cc
+++ b/chrome/browser/push_messaging/push_messaging_service_impl.cc
@@ -37,6 +37,8 @@
#include "components/rappor/rappor_utils.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/notification_database_data.h"
+#include "content/public/browser/platform_notification_context.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/service_worker_context.h"
#include "content/public/browser/storage_partition.h"
@@ -57,6 +59,8 @@
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#endif
+using content::BrowserThread;
+
namespace {
const int kMaxRegistrations = 1000000;
@@ -278,22 +282,59 @@ void PushMessagingServiceImpl::DeliverMessageCallback(
}
void PushMessagingServiceImpl::RequireUserVisibleUX(
- const GURL& requesting_origin, int64 service_worker_registration_id,
+ const GURL& requesting_origin, int64_t service_worker_registration_id,
const base::Closure& message_handled_closure) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
#if defined(ENABLE_NOTIFICATIONS)
// TODO(johnme): Relax this heuristic slightly.
- PlatformNotificationServiceImpl* notification_service =
- PlatformNotificationServiceImpl::GetInstance();
- // Can't use g_browser_process->notification_ui_manager(), since the test uses
- // PlatformNotificationServiceImpl::SetNotificationUIManagerForTesting.
- // TODO(peter): Remove the need to use both APIs here once Notification.get()
- // is supported.
- int notification_count = notification_service->GetNotificationUIManager()->
- GetAllIdsByProfileAndSourceOrigin(profile_, requesting_origin).size();
+ scoped_refptr<content::PlatformNotificationContext> notification_context =
+ content::BrowserContext::GetStoragePartitionForSite(
+ profile_, requesting_origin)->GetPlatformNotificationContext();
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(
+ &content::PlatformNotificationContext
+ ::ReadAllNotificationDataForServiceWorkerRegistration,
+ notification_context,
+ requesting_origin, service_worker_registration_id,
+ base::Bind(
+ &PushMessagingServiceImpl::DidGetNotificationsFromDatabaseIOProxy,
+ weak_factory_.GetWeakPtr(),
+ requesting_origin, service_worker_registration_id,
+ message_handled_closure)));
+#else
+ message_handled_closure.Run();
+#endif // defined(ENABLE_NOTIFICATIONS)
+}
+
+// static
+void PushMessagingServiceImpl::DidGetNotificationsFromDatabaseIOProxy(
+ const base::WeakPtr<PushMessagingServiceImpl>& ui_weak_ptr,
+ const GURL& requesting_origin,
+ int64_t service_worker_registration_id,
+ const base::Closure& message_handled_closure,
+ bool success,
+ const std::vector<content::NotificationDatabaseData>& data) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&PushMessagingServiceImpl::DidGetNotificationsFromDatabase,
+ ui_weak_ptr,
+ requesting_origin, service_worker_registration_id,
+ message_handled_closure,
+ success, data));
+}
+
+void PushMessagingServiceImpl::DidGetNotificationsFromDatabase(
+ const GURL& requesting_origin, int64_t service_worker_registration_id,
+ const base::Closure& message_handled_closure,
+ bool success, const std::vector<content::NotificationDatabaseData>& data) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
// TODO(johnme): Hiding an existing notification should also count as a useful
// user-visible action done in response to a push message - but make sure that
// sending two messages in rapid succession which show then hide a
// notification doesn't count.
+ int notification_count = success ? data.size() : 0;
bool notification_shown = notification_count > 0;
bool notification_needed = true;
@@ -347,7 +388,7 @@ void PushMessagingServiceImpl::RequireUserVisibleUX(
GetNotificationsShownByLastFewPushes(
service_worker_context, service_worker_registration_id,
- base::Bind(&PushMessagingServiceImpl::DidGetNotificationsShown,
+ base::Bind(&PushMessagingServiceImpl::DidGetNotificationsShownAndNeeded,
weak_factory_.GetWeakPtr(),
requesting_origin, service_worker_registration_id,
notification_shown, notification_needed,
@@ -357,19 +398,17 @@ void PushMessagingServiceImpl::RequireUserVisibleUX(
content::PUSH_USER_VISIBLE_STATUS_NOT_REQUIRED_AND_NOT_SHOWN);
message_handled_closure.Run();
}
-#else
- message_handled_closure.Run();
-#endif // defined(ENABLE_NOTIFICATIONS)
}
static void IgnoreResult(bool unused) {
}
-void PushMessagingServiceImpl::DidGetNotificationsShown(
- const GURL& requesting_origin, int64 service_worker_registration_id,
+void PushMessagingServiceImpl::DidGetNotificationsShownAndNeeded(
+ const GURL& requesting_origin, int64_t service_worker_registration_id,
bool notification_shown, bool notification_needed,
const base::Closure& message_handled_closure,
const std::string& data, bool success, bool not_found) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
content::ServiceWorkerContext* service_worker_context =
content::BrowserContext::GetStoragePartitionForSite(
profile_, requesting_origin)->GetServiceWorkerContext();
@@ -429,13 +468,62 @@ void PushMessagingServiceImpl::DidGetNotificationsShown(
notification_data.body =
l10n_util::GetStringUTF16(IDS_PUSH_MESSAGING_GENERIC_NOTIFICATION_BODY);
notification_data.tag = kPushMessagingForcedNotificationTag;
- notification_data.icon = GURL(); // TODO(johnme): Better icon?
+ notification_data.icon = GURL();
notification_data.silent = true;
- PlatformNotificationServiceImpl* notification_service =
- PlatformNotificationServiceImpl::GetInstance();
- notification_service->DisplayPersistentNotification(
+
+ content::NotificationDatabaseData database_data;
+ database_data.origin = requesting_origin;
+ database_data.service_worker_registration_id =
+ service_worker_registration_id;
+ database_data.notification_data = notification_data;
+
+ scoped_refptr<content::PlatformNotificationContext> notification_context =
+ content::BrowserContext::GetStoragePartitionForSite(
+ profile_, requesting_origin)->GetPlatformNotificationContext();
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(
+ &content::PlatformNotificationContext::WriteNotificationData,
+ notification_context,
+ requesting_origin, database_data,
+ base::Bind(&PushMessagingServiceImpl::DidWriteNotificationDataIOProxy,
+ weak_factory_.GetWeakPtr(),
+ requesting_origin, notification_data,
+ message_handled_closure)));
+}
+
+// static
+void PushMessagingServiceImpl::DidWriteNotificationDataIOProxy(
+ const base::WeakPtr<PushMessagingServiceImpl>& ui_weak_ptr,
+ const GURL& requesting_origin,
+ const content::PlatformNotificationData& notification_data,
+ const base::Closure& message_handled_closure,
+ bool success,
+ int64_t persistent_notification_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&PushMessagingServiceImpl::DidWriteNotificationData,
+ ui_weak_ptr,
+ requesting_origin, notification_data, message_handled_closure,
+ success, persistent_notification_id));
+}
+
+void PushMessagingServiceImpl::DidWriteNotificationData(
+ const GURL& requesting_origin,
+ const content::PlatformNotificationData& notification_data,
+ const base::Closure& message_handled_closure,
+ bool success,
+ int64_t persistent_notification_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (!success) {
+ DLOG(ERROR) << "Writing forced notification to database should not fail";
+ message_handled_closure.Run();
+ return;
+ }
+ PlatformNotificationServiceImpl::GetInstance()->DisplayPersistentNotification(
profile_,
- service_worker_registration_id,
+ persistent_notification_id,
requesting_origin,
SkBitmap() /* icon */,
notification_data);
diff --git a/chrome/browser/push_messaging/push_messaging_service_impl.h b/chrome/browser/push_messaging/push_messaging_service_impl.h
index 2a4ed65..1c6370e 100644
--- a/chrome/browser/push_messaging/push_messaging_service_impl.h
+++ b/chrome/browser/push_messaging/push_messaging_service_impl.h
@@ -5,6 +5,8 @@
#ifndef CHROME_BROWSER_PUSH_MESSAGING_PUSH_MESSAGING_SERVICE_IMPL_H_
#define CHROME_BROWSER_PUSH_MESSAGING_PUSH_MESSAGING_SERVICE_IMPL_H_
+#include <stdint.h>
+
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/memory/weak_ptr.h"
@@ -20,8 +22,9 @@
class Profile;
class PushMessagingApplicationId;
-namespace user_prefs {
-class PrefRegistrySyncable;
+namespace content {
+struct NotificationDatabaseData;
+struct PlatformNotificationData;
}
namespace gcm {
@@ -29,6 +32,10 @@ class GCMDriver;
class GCMProfileService;
}
+namespace user_prefs {
+class PrefRegistrySyncable;
+}
+
class PushMessagingServiceImpl : public content::PushMessagingService,
public gcm::GCMAppHandler,
public content_settings::Observer,
@@ -113,11 +120,27 @@ class PushMessagingServiceImpl : public content::PushMessagingService,
// happened in the background. When they forget to do so, display a default
// notification on their behalf.
void RequireUserVisibleUX(const GURL& requesting_origin,
- int64 service_worker_registration_id,
+ int64_t service_worker_registration_id,
const base::Closure& message_handled_closure);
- void DidGetNotificationsShown(
+
+ static void DidGetNotificationsFromDatabaseIOProxy(
+ const base::WeakPtr<PushMessagingServiceImpl>& ui_weak_ptr,
const GURL& requesting_origin,
- int64 service_worker_registration_id,
+ int64_t service_worker_registration_id,
+ const base::Closure& message_handled_closure,
+ bool success,
+ const std::vector<content::NotificationDatabaseData>& data);
+
+ void DidGetNotificationsFromDatabase(
+ const GURL& requesting_origin,
+ int64_t service_worker_registration_id,
+ const base::Closure& message_handled_closure,
+ bool success,
+ const std::vector<content::NotificationDatabaseData>& data);
+
+ void DidGetNotificationsShownAndNeeded(
+ const GURL& requesting_origin,
+ int64_t service_worker_registration_id,
bool notification_shown,
bool notification_needed,
const base::Closure& message_handled_closure,
@@ -125,6 +148,21 @@ class PushMessagingServiceImpl : public content::PushMessagingService,
bool success,
bool not_found);
+ static void DidWriteNotificationDataIOProxy(
+ const base::WeakPtr<PushMessagingServiceImpl>& ui_weak_ptr,
+ const GURL& requesting_origin,
+ const content::PlatformNotificationData& notification_data,
+ const base::Closure& message_handled_closure,
+ bool success,
+ int64_t persistent_notification_id);
+
+ void DidWriteNotificationData(
+ const GURL& requesting_origin,
+ const content::PlatformNotificationData& notification_data,
+ const base::Closure& message_handled_closure,
+ bool success,
+ int64_t persistent_notification_id);
+
// Register methods ----------------------------------------------------------
void RegisterEnd(
diff --git a/content/browser/notifications/platform_notification_context_impl.h b/content/browser/notifications/platform_notification_context_impl.h
index e208324..c6b370d 100644
--- a/content/browser/notifications/platform_notification_context_impl.h
+++ b/content/browser/notifications/platform_notification_context_impl.h
@@ -34,9 +34,7 @@ class ServiceWorkerContextWrapper;
// otherwise specified.
class CONTENT_EXPORT PlatformNotificationContextImpl
: NON_EXPORTED_BASE(public PlatformNotificationContext),
- NON_EXPORTED_BASE(public ServiceWorkerContextObserver),
- public base::RefCountedThreadSafe<PlatformNotificationContextImpl,
- BrowserThread::DeleteOnUIThread> {
+ NON_EXPORTED_BASE(public ServiceWorkerContextObserver) {
public:
// Constructs a new platform notification context. If |path| is non-empty, the
// database will be initialized in the "Platform Notifications" subdirectory
@@ -73,10 +71,6 @@ class CONTENT_EXPORT PlatformNotificationContextImpl
void OnStorageWiped() override;
private:
- friend class base::DeleteHelper<PlatformNotificationContextImpl>;
- friend class base::RefCountedThreadSafe<PlatformNotificationContextImpl,
- BrowserThread::DeleteOnUIThread>;
- friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>;
friend class PlatformNotificationContextTest;
~PlatformNotificationContextImpl() override;
diff --git a/content/public/browser/platform_notification_context.h b/content/public/browser/platform_notification_context.h
index 74dd471..47d6b75 100644
--- a/content/public/browser/platform_notification_context.h
+++ b/content/public/browser/platform_notification_context.h
@@ -9,6 +9,8 @@
#include <vector>
#include "base/callback.h"
+#include "base/memory/ref_counted.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_database_data.h"
class GURL;
@@ -18,7 +20,9 @@ namespace content {
// Represents the storage context for persistent Web Notifications, specific to
// the storage partition owning the instance. All methods defined in this
// interface may only be used on the IO thread.
-class PlatformNotificationContext {
+class PlatformNotificationContext
+ : public base::RefCountedThreadSafe<PlatformNotificationContext,
+ BrowserThread::DeleteOnUIThread> {
public:
using ReadResultCallback =
base::Callback<void(bool /* success */,
@@ -65,6 +69,9 @@ class PlatformNotificationContext {
const DeleteResultCallback& callback) = 0;
protected:
+ friend class base::DeleteHelper<PlatformNotificationContext>;
+ friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>;
+
virtual ~PlatformNotificationContext() {}
};