| Index: chrome/browser/push_messaging/push_messaging_service_impl.cc
|
| diff --git a/chrome/browser/push_messaging/push_messaging_service_impl.cc b/chrome/browser/push_messaging/push_messaging_service_impl.cc
|
| index c26b3b516a26c702388a1f419c5111059c2671d2..2c50f9212ed98278f0b9fbf8111bb4f75fdbcb13 100644
|
| --- a/chrome/browser/push_messaging/push_messaging_service_impl.cc
|
| +++ b/chrome/browser/push_messaging/push_messaging_service_impl.cc
|
| @@ -21,6 +21,7 @@
|
| #include "chrome/browser/push_messaging/push_messaging_app_identifier.h"
|
| #include "chrome/browser/push_messaging/push_messaging_constants.h"
|
| #include "chrome/browser/push_messaging/push_messaging_service_factory.h"
|
| +#include "chrome/browser/push_messaging/push_messaging_service_observer.h"
|
| #include "chrome/browser/services/gcm/gcm_profile_service_factory.h"
|
| #include "chrome/browser/ui/chrome_pages.h"
|
| #include "chrome/common/chrome_switches.h"
|
| @@ -121,6 +122,7 @@ PushMessagingServiceImpl::PushMessagingServiceImpl(Profile* profile)
|
| #if defined(ENABLE_NOTIFICATIONS)
|
| notification_manager_(profile),
|
| #endif
|
| + push_messaging_service_observer_(PushMessagingServiceObserver::Create()),
|
| weak_factory_(this) {
|
| DCHECK(profile);
|
| HostContentSettingsMapFactory::GetForProfile(profile_)->AddObserver(this);
|
| @@ -242,13 +244,12 @@ void PushMessagingServiceImpl::DeliverMessageCallback(
|
| const gcm::IncomingMessage& message,
|
| const base::Closure& message_handled_closure,
|
| content::PushDeliveryStatus status) {
|
| - // Remove a single in-flight delivery for |app_id|. This has to be done using
|
| - // an iterator rather than by value, as the latter removes all entries.
|
| - DCHECK(in_flight_message_deliveries_.find(app_id) !=
|
| - in_flight_message_deliveries_.end());
|
| + DCHECK_GE(in_flight_message_deliveries_.count(app_id), 1u);
|
|
|
| - in_flight_message_deliveries_.erase(
|
| - in_flight_message_deliveries_.find(app_id));
|
| + // TODO(mvanouwerkerk): Use ScopedClosureRunner for this.
|
| + base::Closure completion_closure =
|
| + base::Bind(&PushMessagingServiceImpl::DidHandleMessage,
|
| + weak_factory_.GetWeakPtr(), app_id, message_handled_closure);
|
|
|
| // TODO(mvanouwerkerk): Show a warning in the developer console of the
|
| // Service Worker corresponding to app_id (and/or on an internals page).
|
| @@ -261,35 +262,50 @@ void PushMessagingServiceImpl::DeliverMessageCallback(
|
| case content::PUSH_DELIVERY_STATUS_SUCCESS:
|
| case content::PUSH_DELIVERY_STATUS_EVENT_WAITUNTIL_REJECTED:
|
| #if defined(ENABLE_NOTIFICATIONS)
|
| - // Only enforce the user visible requirements after the entire queue of
|
| - // incoming messages for |app_id| has been flushed.
|
| - if (!in_flight_message_deliveries_.count(app_id)) {
|
| + // Only enforce the user visible requirements if this is currently running
|
| + // as the delivery callback for the last in-flight message.
|
| + if (in_flight_message_deliveries_.count(app_id) == 1) {
|
| notification_manager_.EnforceUserVisibleOnlyRequirements(
|
| requesting_origin, service_worker_registration_id,
|
| - message_handled_closure);
|
| + completion_closure);
|
| } else {
|
| - message_handled_closure.Run();
|
| + completion_closure.Run();
|
| }
|
| #else
|
| - message_handled_closure.Run();
|
| + completion_closure.Run();
|
| #endif
|
| break;
|
| case content::PUSH_DELIVERY_STATUS_INVALID_MESSAGE:
|
| case content::PUSH_DELIVERY_STATUS_SERVICE_WORKER_ERROR:
|
| - message_handled_closure.Run();
|
| + completion_closure.Run();
|
| break;
|
| case content::PUSH_DELIVERY_STATUS_UNKNOWN_APP_ID:
|
| case content::PUSH_DELIVERY_STATUS_PERMISSION_DENIED:
|
| case content::PUSH_DELIVERY_STATUS_NO_SERVICE_WORKER:
|
| - Unsubscribe(
|
| - app_id, message.sender_id,
|
| - base::Bind(&UnregisterCallbackToClosure, message_handled_closure));
|
| + Unsubscribe(app_id, message.sender_id,
|
| + base::Bind(&UnregisterCallbackToClosure, completion_closure));
|
| break;
|
| }
|
|
|
| RecordDeliveryStatus(status);
|
| }
|
|
|
| +void PushMessagingServiceImpl::DidHandleMessage(
|
| + const std::string& app_id,
|
| + const base::Closure& message_handled_closure) {
|
| + auto in_flight_iterator = in_flight_message_deliveries_.find(app_id);
|
| + DCHECK(in_flight_iterator != in_flight_message_deliveries_.end());
|
| +
|
| + // Remove a single in-flight delivery for |app_id|. This has to be done using
|
| + // an iterator rather than by value, as the latter removes all entries.
|
| + in_flight_message_deliveries_.erase(in_flight_iterator);
|
| +
|
| + message_handled_closure.Run();
|
| +
|
| + if (push_messaging_service_observer_)
|
| + push_messaging_service_observer_->OnMessageHandled();
|
| +}
|
| +
|
| void PushMessagingServiceImpl::SetMessageCallbackForTesting(
|
| const base::Closure& callback) {
|
| message_callback_for_testing_ = callback;
|
|
|