| 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 1abf01d9a8645ff9ebf25dece626523f1b2b5672..fbc0c0e932ff2eed5caf85631cf94baaf31b131f 100644
|
| --- a/chrome/browser/push_messaging/push_messaging_service_impl.cc
|
| +++ b/chrome/browser/push_messaging/push_messaging_service_impl.cc
|
| @@ -90,6 +90,16 @@ void RecordUnsubscribeReason(content::PushUnregistrationReason reason) {
|
| content::PUSH_UNREGISTRATION_REASON_LAST + 1);
|
| }
|
|
|
| +void RecordUnsubscribeGCMResult(gcm::GCMClient::Result result) {
|
| + UMA_HISTOGRAM_ENUMERATION("PushMessaging.UnregistrationGCMResult", result,
|
| + gcm::GCMClient::LAST_RESULT + 1);
|
| +}
|
| +
|
| +void RecordUnsubscribeIIDResult(InstanceID::Result result) {
|
| + UMA_HISTOGRAM_ENUMERATION("PushMessaging.UnregistrationIIDResult", result,
|
| + InstanceID::LAST_RESULT + 1);
|
| +}
|
| +
|
| blink::WebPushPermissionStatus ToPushPermission(
|
| blink::mojom::PermissionStatus permission_status) {
|
| switch (permission_status) {
|
| @@ -104,50 +114,6 @@ blink::WebPushPermissionStatus ToPushPermission(
|
| return blink::WebPushPermissionStatusDenied;
|
| }
|
|
|
| -content::PushUnregistrationStatus ToUnregisterStatus(
|
| - InstanceID::Result result) {
|
| - switch (result) {
|
| - case InstanceID::SUCCESS:
|
| - return content::PUSH_UNREGISTRATION_STATUS_SUCCESS_UNREGISTERED;
|
| - case InstanceID::INVALID_PARAMETER:
|
| - case InstanceID::DISABLED:
|
| - case InstanceID::SERVER_ERROR:
|
| - case InstanceID::UNKNOWN_ERROR:
|
| - return content::PUSH_UNREGISTRATION_STATUS_PENDING_SERVICE_ERROR;
|
| - case InstanceID::ASYNC_OPERATION_PENDING:
|
| - case InstanceID::NETWORK_ERROR:
|
| - return content::PUSH_UNREGISTRATION_STATUS_PENDING_NETWORK_ERROR;
|
| - }
|
| - NOTREACHED();
|
| - return content::PUSH_UNREGISTRATION_STATUS_SERVICE_NOT_AVAILABLE;
|
| -}
|
| -
|
| -content::PushUnregistrationStatus ToUnregisterStatus(
|
| - gcm::GCMClient::Result gcm_result) {
|
| - switch (gcm_result) {
|
| - case gcm::GCMClient::SUCCESS:
|
| - return content::PUSH_UNREGISTRATION_STATUS_SUCCESS_UNREGISTERED;
|
| - case gcm::GCMClient::INVALID_PARAMETER:
|
| - case gcm::GCMClient::GCM_DISABLED:
|
| - case gcm::GCMClient::SERVER_ERROR:
|
| - case gcm::GCMClient::UNKNOWN_ERROR:
|
| - return content::PUSH_UNREGISTRATION_STATUS_PENDING_SERVICE_ERROR;
|
| - case gcm::GCMClient::ASYNC_OPERATION_PENDING:
|
| - case gcm::GCMClient::NETWORK_ERROR:
|
| - case gcm::GCMClient::TTL_EXCEEDED:
|
| - return content::PUSH_UNREGISTRATION_STATUS_PENDING_NETWORK_ERROR;
|
| - }
|
| - NOTREACHED();
|
| - return content::PUSH_UNREGISTRATION_STATUS_SERVICE_NOT_AVAILABLE;
|
| -}
|
| -
|
| -void GCMCallbackToUnregisterCallback(
|
| - const content::PushMessagingService::UnregisterCallback& callback,
|
| - gcm::GCMClient::Result result) {
|
| - DCHECK(!callback.is_null());
|
| - callback.Run(ToUnregisterStatus(result));
|
| -}
|
| -
|
| void UnregisterCallbackToClosure(const base::Closure& closure,
|
| content::PushUnregistrationStatus status) {
|
| DCHECK(!closure.is_null());
|
| @@ -761,18 +727,27 @@ void PushMessagingServiceImpl::DidClearPushSubscriptionId(
|
| if (was_subscribed)
|
| app_identifier.DeleteFromPrefs(profile_);
|
|
|
| + // Run the unsubscribe callback *before* asking the InstanceIDDriver/GCMDriver
|
| + // to unsubscribe, since that's a slow process involving network retries, and
|
| + // by this point enough local state has been deleted that the subscription is
|
| + // inactive. Note that DeliverMessageCallback automatically unsubscribes if
|
| + // messages are later received for a subscription that was locally deleted,
|
| + // so as long as messages keep getting sent to it, the unsubscription should
|
| + // eventually reach GCM servers even if this particular attempt fails.
|
| + callback.Run(
|
| + was_subscribed
|
| + ? content::PUSH_UNREGISTRATION_STATUS_SUCCESS_UNREGISTERED
|
| + : content::PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED);
|
| +
|
| if (PushMessagingAppIdentifier::UseInstanceID(app_id)) {
|
| - GetInstanceIDDriver()->GetInstanceID(app_id)->DeleteID(base::Bind(
|
| - &PushMessagingServiceImpl::DidDeleteID, weak_factory_.GetWeakPtr(),
|
| - app_id, was_subscribed, callback));
|
| + GetInstanceIDDriver()->GetInstanceID(app_id)->DeleteID(
|
| + base::Bind(&PushMessagingServiceImpl::DidDeleteID,
|
| + weak_factory_.GetWeakPtr(), app_id, was_subscribed));
|
|
|
| } else {
|
| auto unregister_callback =
|
| - base::Bind(&GCMCallbackToUnregisterCallback,
|
| - base::Bind(&PushMessagingServiceImpl::DidUnsubscribe,
|
| - weak_factory_.GetWeakPtr(),
|
| - std::string() /* app_id_when_instance_id */,
|
| - was_subscribed, callback));
|
| + base::Bind(&PushMessagingServiceImpl::DidUnregister,
|
| + weak_factory_.GetWeakPtr(), was_subscribed);
|
| #if defined(OS_ANDROID)
|
| // On Android the backend is different, and requires the original sender_id.
|
| // UnsubscribeBecausePermissionRevoked and
|
| @@ -789,38 +764,42 @@ void PushMessagingServiceImpl::DidClearPushSubscriptionId(
|
| }
|
| }
|
|
|
| +void PushMessagingServiceImpl::DidUnregister(bool was_subscribed,
|
| + gcm::GCMClient::Result result) {
|
| + RecordUnsubscribeGCMResult(result);
|
| + DidUnsubscribe(std::string() /* app_id_when_instance_id */, was_subscribed);
|
| +}
|
| +
|
| void PushMessagingServiceImpl::DidDeleteID(const std::string& app_id,
|
| bool was_subscribed,
|
| - const UnregisterCallback& callback,
|
| InstanceID::Result result) {
|
| + RecordUnsubscribeIIDResult(result);
|
| // DidUnsubscribe must be run asynchronously when passing a non-empty
|
| // |app_id_when_instance_id|, since it calls
|
| // InstanceIDDriver::RemoveInstanceID which deletes the InstanceID itself.
|
| // Calling that immediately would cause a use-after-free in our caller.
|
| base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| - FROM_HERE, base::Bind(&PushMessagingServiceImpl::DidUnsubscribe,
|
| - weak_factory_.GetWeakPtr(), app_id, was_subscribed,
|
| - callback, ToUnregisterStatus(result)));
|
| + FROM_HERE,
|
| + base::Bind(&PushMessagingServiceImpl::DidUnsubscribe,
|
| + weak_factory_.GetWeakPtr(), app_id, was_subscribed));
|
| }
|
|
|
| void PushMessagingServiceImpl::DidUnsubscribe(
|
| const std::string& app_id_when_instance_id,
|
| - bool was_subscribed,
|
| - const UnregisterCallback& callback,
|
| - content::PushUnregistrationStatus status) {
|
| + bool was_subscribed) {
|
| if (!app_id_when_instance_id.empty())
|
| GetInstanceIDDriver()->RemoveInstanceID(app_id_when_instance_id);
|
|
|
| - DCHECK(!callback.is_null());
|
| -
|
| - if (was_subscribed) {
|
| + if (was_subscribed)
|
| DecreasePushSubscriptionCount(1, false /* was_pending */);
|
| - callback.Run(status);
|
| - } else {
|
| - // Override status since there was no record of an existing subscription.
|
| - callback.Run(
|
| - content::PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED);
|
| - }
|
| +
|
| + if (!unsubscribe_callback_for_testing_.is_null())
|
| + unsubscribe_callback_for_testing_.Run();
|
| +}
|
| +
|
| +void PushMessagingServiceImpl::SetUnsubscribeCallbackForTesting(
|
| + const base::Closure& callback) {
|
| + unsubscribe_callback_for_testing_ = callback;
|
| }
|
|
|
| // DidDeleteServiceWorkerRegistration methods ----------------------------------
|
|
|