Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1336)

Side by Side Diff: chrome/browser/push_messaging/push_messaging_service_impl.cc

Issue 2387483002: Push API: Refactor and fix unsubscribe API (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/push_messaging/push_messaging_service_impl.h" 5 #include "chrome/browser/push_messaging/push_messaging_service_impl.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/barrier_closure.h" 9 #include "base/barrier_closure.h"
10 #include "base/base64url.h" 10 #include "base/base64url.h"
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 "Chrome currently only supports the Push API for subscriptions that will " 76 "Chrome currently only supports the Push API for subscriptions that will "
77 "result in user-visible messages. You can indicate this by calling " 77 "result in user-visible messages. You can indicate this by calling "
78 "pushManager.subscribe({userVisibleOnly: true}) instead. See " 78 "pushManager.subscribe({userVisibleOnly: true}) instead. See "
79 "https://goo.gl/yqv4Q4 for more details."; 79 "https://goo.gl/yqv4Q4 for more details.";
80 80
81 void RecordDeliveryStatus(content::PushDeliveryStatus status) { 81 void RecordDeliveryStatus(content::PushDeliveryStatus status) {
82 UMA_HISTOGRAM_ENUMERATION("PushMessaging.DeliveryStatus", status, 82 UMA_HISTOGRAM_ENUMERATION("PushMessaging.DeliveryStatus", status,
83 content::PUSH_DELIVERY_STATUS_LAST + 1); 83 content::PUSH_DELIVERY_STATUS_LAST + 1);
84 } 84 }
85 85
86 void RecordUnsubscribeReason(content::PushUnregistrationReason reason) {
87 UMA_HISTOGRAM_ENUMERATION("PushMessaging.UnregistrationReason", reason,
88 content::PUSH_UNREGISTRATION_REASON_LAST + 1);
89 }
90
86 blink::WebPushPermissionStatus ToPushPermission( 91 blink::WebPushPermissionStatus ToPushPermission(
87 blink::mojom::PermissionStatus permission_status) { 92 blink::mojom::PermissionStatus permission_status) {
88 switch (permission_status) { 93 switch (permission_status) {
89 case blink::mojom::PermissionStatus::GRANTED: 94 case blink::mojom::PermissionStatus::GRANTED:
90 return blink::WebPushPermissionStatusGranted; 95 return blink::WebPushPermissionStatusGranted;
91 case blink::mojom::PermissionStatus::DENIED: 96 case blink::mojom::PermissionStatus::DENIED:
92 return blink::WebPushPermissionStatusDenied; 97 return blink::WebPushPermissionStatusDenied;
93 case blink::mojom::PermissionStatus::ASK: 98 case blink::mojom::PermissionStatus::ASK:
94 return blink::WebPushPermissionStatusPrompt; 99 return blink::WebPushPermissionStatusPrompt;
95 default: 100 default:
96 NOTREACHED(); 101 NOTREACHED();
97 return blink::WebPushPermissionStatusDenied; 102 return blink::WebPushPermissionStatusDenied;
98 } 103 }
99 } 104 }
100 105
106 content::PushUnregistrationStatus ToUnregisterStatus(
107 InstanceID::Result result) {
108 switch (result) {
109 case InstanceID::SUCCESS:
110 return content::PUSH_UNREGISTRATION_STATUS_SUCCESS_UNREGISTERED;
111 case InstanceID::INVALID_PARAMETER:
112 case InstanceID::DISABLED:
113 case InstanceID::SERVER_ERROR:
114 case InstanceID::UNKNOWN_ERROR:
115 return content::PUSH_UNREGISTRATION_STATUS_PENDING_SERVICE_ERROR;
116 case InstanceID::ASYNC_OPERATION_PENDING:
117 case InstanceID::NETWORK_ERROR:
118 return content::PUSH_UNREGISTRATION_STATUS_PENDING_NETWORK_ERROR;
119 }
Peter Beverloo 2016/09/30 14:26:06 Most compilers will want you to return a default v
johnme 2016/09/30 17:02:09 No, default is evil! It prevents compilers from wa
120 }
121
122 content::PushUnregistrationStatus ToUnregisterStatus(
123 gcm::GCMClient::Result gcm_result) {
124 switch (gcm_result) {
125 case gcm::GCMClient::SUCCESS:
126 return content::PUSH_UNREGISTRATION_STATUS_SUCCESS_UNREGISTERED;
127 case gcm::GCMClient::INVALID_PARAMETER:
128 case gcm::GCMClient::GCM_DISABLED:
129 case gcm::GCMClient::SERVER_ERROR:
130 case gcm::GCMClient::UNKNOWN_ERROR:
131 return content::PUSH_UNREGISTRATION_STATUS_PENDING_SERVICE_ERROR;
132 case gcm::GCMClient::ASYNC_OPERATION_PENDING:
133 case gcm::GCMClient::NETWORK_ERROR:
134 case gcm::GCMClient::TTL_EXCEEDED:
135 return content::PUSH_UNREGISTRATION_STATUS_PENDING_NETWORK_ERROR;
136 }
137 }
138
139 void GCMCallbackToUnregisterCallback(
140 const content::PushMessagingService::UnregisterCallback& callback,
141 gcm::GCMClient::Result result) {
142 DCHECK(!callback.is_null());
143 callback.Run(ToUnregisterStatus(result));
144 }
145
101 void UnregisterCallbackToClosure(const base::Closure& closure, 146 void UnregisterCallbackToClosure(const base::Closure& closure,
102 content::PushUnregistrationStatus status) { 147 content::PushUnregistrationStatus status) {
148 DCHECK(!closure.is_null());
103 closure.Run(); 149 closure.Run();
104 } 150 }
105 151
106 #if BUILDFLAG(ENABLE_BACKGROUND) 152 #if BUILDFLAG(ENABLE_BACKGROUND)
107 bool UseBackgroundMode() { 153 bool UseBackgroundMode() {
108 // Note: if push is ever enabled in incognito, the background mode integration 154 // Note: if push is ever enabled in incognito, the background mode integration
109 // should not be enabled for it. 155 // should not be enabled for it.
110 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); 156 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
111 if (command_line->HasSwitch(switches::kDisablePushApiBackgroundMode)) 157 if (command_line->HasSwitch(switches::kDisablePushApiBackgroundMode))
112 return false; 158 return false;
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 } 275 }
230 #endif 276 #endif
231 277
232 base::Closure message_handled_closure = 278 base::Closure message_handled_closure =
233 message_callback_for_testing_.is_null() ? base::Bind(&base::DoNothing) 279 message_callback_for_testing_.is_null() ? base::Bind(&base::DoNothing)
234 : message_callback_for_testing_; 280 : message_callback_for_testing_;
235 PushMessagingAppIdentifier app_identifier = 281 PushMessagingAppIdentifier app_identifier =
236 PushMessagingAppIdentifier::FindByAppId(profile_, app_id); 282 PushMessagingAppIdentifier::FindByAppId(profile_, app_id);
237 // Drop message and unregister if app_id was unknown (maybe recently deleted). 283 // Drop message and unregister if app_id was unknown (maybe recently deleted).
238 if (app_identifier.is_null()) { 284 if (app_identifier.is_null()) {
239 DeliverMessageCallback(app_id, GURL::EmptyGURL(), -1, message, 285 DeliverMessageCallback(app_id, GURL::EmptyGURL(),
240 message_handled_closure, 286 -1 /* kInvalidServiceWorkerRegistrationId */,
287 message, message_handled_closure,
241 content::PUSH_DELIVERY_STATUS_UNKNOWN_APP_ID); 288 content::PUSH_DELIVERY_STATUS_UNKNOWN_APP_ID);
242 return; 289 return;
243 } 290 }
244 // Drop message and unregister if |origin| has lost push permission. 291 // Drop message and unregister if |origin| has lost push permission.
245 if (!IsPermissionSet(app_identifier.origin())) { 292 if (!IsPermissionSet(app_identifier.origin())) {
246 DeliverMessageCallback(app_id, app_identifier.origin(), 293 DeliverMessageCallback(app_id, app_identifier.origin(),
247 app_identifier.service_worker_registration_id(), 294 app_identifier.service_worker_registration_id(),
248 message, message_handled_closure, 295 message, message_handled_closure,
249 content::PUSH_DELIVERY_STATUS_PERMISSION_DENIED); 296 content::PUSH_DELIVERY_STATUS_PERMISSION_DENIED);
250 return; 297 return;
(...skipping 29 matching lines...) Expand all
280 327
281 void PushMessagingServiceImpl::DeliverMessageCallback( 328 void PushMessagingServiceImpl::DeliverMessageCallback(
282 const std::string& app_id, 329 const std::string& app_id,
283 const GURL& requesting_origin, 330 const GURL& requesting_origin,
284 int64_t service_worker_registration_id, 331 int64_t service_worker_registration_id,
285 const gcm::IncomingMessage& message, 332 const gcm::IncomingMessage& message,
286 const base::Closure& message_handled_closure, 333 const base::Closure& message_handled_closure,
287 content::PushDeliveryStatus status) { 334 content::PushDeliveryStatus status) {
288 DCHECK_GE(in_flight_message_deliveries_.count(app_id), 1u); 335 DCHECK_GE(in_flight_message_deliveries_.count(app_id), 1u);
289 336
337 RecordDeliveryStatus(status);
338
290 base::Closure completion_closure = 339 base::Closure completion_closure =
291 base::Bind(&PushMessagingServiceImpl::DidHandleMessage, 340 base::Bind(&PushMessagingServiceImpl::DidHandleMessage,
292 weak_factory_.GetWeakPtr(), app_id, message_handled_closure); 341 weak_factory_.GetWeakPtr(), app_id, message_handled_closure);
293 // The completion_closure should run by default at the end of this function, 342 // The completion_closure should run by default at the end of this function,
294 // unless it is explicitly passed to another function. 343 // unless it is explicitly passed to another function.
295 base::ScopedClosureRunner completion_closure_runner(completion_closure); 344 base::ScopedClosureRunner completion_closure_runner(completion_closure);
296 345
346 // Dummy reason meaning this function should not automatically unsubscribe.
347 const content::PushUnregistrationReason DO_NOT_UNSUBSCRIBE =
348 content::PUSH_UNREGISTRATION_REASON_JAVASCRIPT_API;
Peter Beverloo 2016/09/30 14:26:06 What about defining a PUSH_UNREGISTRATION_REASON_U
johnme 2016/09/30 17:02:10 Done.
349
350 // Whether and why automatic unsubscription is necessary.
351 content::PushUnregistrationReason unsubscribe_reason = DO_NOT_UNSUBSCRIBE;
352
297 // TODO(mvanouwerkerk): Show a warning in the developer console of the 353 // TODO(mvanouwerkerk): Show a warning in the developer console of the
298 // Service Worker corresponding to app_id (and/or on an internals page). 354 // Service Worker corresponding to app_id (and/or on an internals page).
299 // See https://crbug.com/508516 for options. 355 // See https://crbug.com/508516 for options.
300 switch (status) { 356 switch (status) {
301 // Call EnforceUserVisibleOnlyRequirements if the message was delivered to 357 // Call EnforceUserVisibleOnlyRequirements if the message was delivered to
302 // the Service Worker JavaScript, even if the website's event handler failed 358 // the Service Worker JavaScript, even if the website's event handler failed
303 // (to prevent sites deliberately failing in order to avoid having to show 359 // (to prevent sites deliberately failing in order to avoid having to show
304 // notifications). 360 // notifications).
305 case content::PUSH_DELIVERY_STATUS_SUCCESS: 361 case content::PUSH_DELIVERY_STATUS_SUCCESS:
306 case content::PUSH_DELIVERY_STATUS_EVENT_WAITUNTIL_REJECTED: 362 case content::PUSH_DELIVERY_STATUS_EVENT_WAITUNTIL_REJECTED:
307 #if defined(ENABLE_NOTIFICATIONS) 363 #if defined(ENABLE_NOTIFICATIONS)
308 // Only enforce the user visible requirements if this is currently running 364 // Only enforce the user visible requirements if this is currently running
309 // as the delivery callback for the last in-flight message, and silent 365 // as the delivery callback for the last in-flight message, and silent
310 // push has not been enabled through a command line flag. 366 // push has not been enabled through a command line flag.
311 if (in_flight_message_deliveries_.count(app_id) == 1 && 367 if (in_flight_message_deliveries_.count(app_id) == 1 &&
312 !base::CommandLine::ForCurrentProcess()->HasSwitch( 368 !base::CommandLine::ForCurrentProcess()->HasSwitch(
313 switches::kAllowSilentPush)) { 369 switches::kAllowSilentPush)) {
314 notification_manager_.EnforceUserVisibleOnlyRequirements( 370 notification_manager_.EnforceUserVisibleOnlyRequirements(
315 requesting_origin, service_worker_registration_id, 371 requesting_origin, service_worker_registration_id,
316 completion_closure_runner.Release()); 372 completion_closure_runner.Release());
317 } 373 }
318 #endif 374 #endif
319 break; 375 break;
320 case content::PUSH_DELIVERY_STATUS_SERVICE_WORKER_ERROR: 376 case content::PUSH_DELIVERY_STATUS_SERVICE_WORKER_ERROR:
377 // Do nothing, and hope the error is transient.
321 break; 378 break;
322 case content::PUSH_DELIVERY_STATUS_UNKNOWN_APP_ID: 379 case content::PUSH_DELIVERY_STATUS_UNKNOWN_APP_ID:
380 unsubscribe_reason =
381 content::PUSH_UNREGISTRATION_REASON_DELIVERY_UNKNOWN_APP_ID;
382 break;
323 case content::PUSH_DELIVERY_STATUS_PERMISSION_DENIED: 383 case content::PUSH_DELIVERY_STATUS_PERMISSION_DENIED:
384 unsubscribe_reason =
385 content::PUSH_UNREGISTRATION_REASON_DELIVERY_PERMISSION_DENIED;
386 break;
324 case content::PUSH_DELIVERY_STATUS_NO_SERVICE_WORKER: 387 case content::PUSH_DELIVERY_STATUS_NO_SERVICE_WORKER:
325 Unsubscribe(app_id, message.sender_id, 388 unsubscribe_reason =
326 base::Bind(&UnregisterCallbackToClosure, 389 content::PUSH_UNREGISTRATION_REASON_DELIVERY_NO_SERVICE_WORKER;
327 completion_closure_runner.Release()));
328 break; 390 break;
329 } 391 }
330 392
331 RecordDeliveryStatus(status); 393 if (unsubscribe_reason != DO_NOT_UNSUBSCRIBE) {
394 PushMessagingAppIdentifier app_identifier =
395 PushMessagingAppIdentifier::FindByAppId(profile_, app_id);
396 UnsubscribeInternal(
397 unsubscribe_reason,
398 app_identifier.is_null() ? GURL::EmptyGURL() : app_identifier.origin(),
399 app_identifier.is_null()
400 ? -1 /* kInvalidServiceWorkerRegistrationId */
401 : app_identifier.service_worker_registration_id(),
402 app_id, message.sender_id,
403 base::Bind(&UnregisterCallbackToClosure,
404 completion_closure_runner.Release()));
405 }
332 } 406 }
333 407
334 void PushMessagingServiceImpl::DidHandleMessage( 408 void PushMessagingServiceImpl::DidHandleMessage(
335 const std::string& app_id, 409 const std::string& app_id,
336 const base::Closure& message_handled_closure) { 410 const base::Closure& message_handled_closure) {
337 auto in_flight_iterator = in_flight_message_deliveries_.find(app_id); 411 auto in_flight_iterator = in_flight_message_deliveries_.find(app_id);
338 DCHECK(in_flight_iterator != in_flight_message_deliveries_.end()); 412 DCHECK(in_flight_iterator != in_flight_message_deliveries_.end());
339 413
340 // Remove a single in-flight delivery for |app_id|. This has to be done using 414 // Remove a single in-flight delivery for |app_id|. This has to be done using
341 // an iterator rather than by value, as the latter removes all entries. 415 // an iterator rather than by value, as the latter removes all entries.
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 // Unsubscribe methods --------------------------------------------------------- 681 // Unsubscribe methods ---------------------------------------------------------
608 682
609 void PushMessagingServiceImpl::Unsubscribe( 683 void PushMessagingServiceImpl::Unsubscribe(
610 const GURL& requesting_origin, 684 const GURL& requesting_origin,
611 int64_t service_worker_registration_id, 685 int64_t service_worker_registration_id,
612 const std::string& sender_id, 686 const std::string& sender_id,
613 const content::PushMessagingService::UnregisterCallback& callback) { 687 const content::PushMessagingService::UnregisterCallback& callback) {
614 PushMessagingAppIdentifier app_identifier = 688 PushMessagingAppIdentifier app_identifier =
615 PushMessagingAppIdentifier::FindByServiceWorker( 689 PushMessagingAppIdentifier::FindByServiceWorker(
616 profile_, requesting_origin, service_worker_registration_id); 690 profile_, requesting_origin, service_worker_registration_id);
617 if (app_identifier.is_null()) { 691
692 UnsubscribeInternal(
693 content::PUSH_UNREGISTRATION_REASON_JAVASCRIPT_API, requesting_origin,
694 service_worker_registration_id,
695 app_identifier.is_null() ? std::string() : app_identifier.app_id(),
696 sender_id, callback);
697 }
698
699 void PushMessagingServiceImpl::UnsubscribeInternal(
700 content::PushUnregistrationReason reason,
701 const GURL& origin,
702 int64_t service_worker_registration_id,
703 const std::string& app_id,
704 const std::string& sender_id,
705 const content::PushMessagingService::UnregisterCallback& callback) {
706 DCHECK(!app_id.empty() || (!origin.is_empty() &&
707 service_worker_registration_id !=
708 -1 /* kInvalidServiceWorkerRegistrationId */))
709 << "Need an app_id and/or origin+service_worker_registration_id";
710
711 RecordUnsubscribeReason(reason);
712
713 if (origin.is_empty() ||
714 service_worker_registration_id ==
715 -1 /* kInvalidServiceWorkerRegistrationId */) {
716 // Can't clear Service Worker database.
717 DidClearPushSubscriptionId(reason, app_id, sender_id, callback);
718 return;
719 }
720 ClearPushSubscriptionId(
721 profile_, origin, service_worker_registration_id,
722 base::Bind(&PushMessagingServiceImpl::DidClearPushSubscriptionId,
723 weak_factory_.GetWeakPtr(), reason, app_id, sender_id,
724 callback));
725 }
726
727 void PushMessagingServiceImpl::DidClearPushSubscriptionId(
728 content::PushUnregistrationReason reason,
729 const std::string& app_id,
730 const std::string& sender_id,
731 const content::PushMessagingService::UnregisterCallback& callback) {
Peter Beverloo 2016/09/30 14:26:06 Specific to UnregisterCallback, since this is the
Peter Beverloo 2016/09/30 14:26:06 We probably want to have a `using` statement in th
johnme 2016/09/30 17:02:10 I just removed all occurrences of (content::)?Push
johnme 2016/09/30 17:02:10 I just removed all occurrences of (content::)?Push
732 if (app_id.empty()) {
733 // There's nothing more we can do.
Peter Beverloo 2016/09/30 14:26:06 // We cannot unsubscribe with the GCM Driver witho
johnme 2016/09/30 17:02:10 Done (expanded to cover PushMessagingAppIdentifier
618 callback.Run( 734 callback.Run(
619 content::PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED); 735 content::PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED);
620 return; 736 return;
621 } 737 }
622 738
623 Unsubscribe(app_identifier.app_id(), sender_id, callback);
624 }
625
626 void PushMessagingServiceImpl::Unsubscribe(
627 const std::string& app_id,
628 const std::string& sender_id,
629 const content::PushMessagingService::UnregisterCallback& callback) {
630 // Delete the mapping for this app_id, to guarantee that no messages get 739 // Delete the mapping for this app_id, to guarantee that no messages get
631 // delivered in future (even if unregistration fails). 740 // delivered in future (even if unregistration fails).
632 // TODO(johnme): Instead of deleting these app ids, store them elsewhere, and 741 // TODO(johnme): Instead of deleting these app ids, store them elsewhere, and
633 // retry unregistration if it fails due to network errors (crbug.com/465399). 742 // retry unregistration if it fails due to network errors (crbug.com/465399).
634 PushMessagingAppIdentifier app_identifier = 743 PushMessagingAppIdentifier app_identifier =
635 PushMessagingAppIdentifier::FindByAppId(profile_, app_id); 744 PushMessagingAppIdentifier::FindByAppId(profile_, app_id);
636 bool was_subscribed = !app_identifier.is_null(); 745 bool was_subscribed = !app_identifier.is_null();
637 if (was_subscribed) 746 if (was_subscribed)
638 app_identifier.DeleteFromPrefs(profile_); 747 app_identifier.DeleteFromPrefs(profile_);
639 748
640 if (PushMessagingAppIdentifier::UseInstanceID(app_id)) { 749 if (PushMessagingAppIdentifier::UseInstanceID(app_id)) {
641 GetInstanceIDDriver()->GetInstanceID(app_id)->DeleteID(base::Bind( 750 GetInstanceIDDriver()->GetInstanceID(app_id)->DeleteID(base::Bind(
642 &PushMessagingServiceImpl::DidDeleteID, weak_factory_.GetWeakPtr(), 751 &PushMessagingServiceImpl::DidDeleteID, weak_factory_.GetWeakPtr(),
643 app_id, was_subscribed, callback)); 752 app_id, was_subscribed, callback));
753
644 } else { 754 } else {
645 auto unregister_callback = 755 auto unregister_callback =
646 base::Bind(&PushMessagingServiceImpl::DidUnsubscribe, 756 base::Bind(&GCMCallbackToUnregisterCallback,
647 weak_factory_.GetWeakPtr(), was_subscribed, callback); 757 base::Bind(&PushMessagingServiceImpl::DidUnsubscribe,
758 weak_factory_.GetWeakPtr(),
759 std::string() /* app_id_if_was_instance_id */,
760 was_subscribed, callback));
648 #if defined(OS_ANDROID) 761 #if defined(OS_ANDROID)
649 // On Android the backend is different, and requires the original sender_id. 762 // On Android the backend is different, and requires the original sender_id.
650 // UnsubscribeBecausePermissionRevoked sometimes calls us with an empty one. 763 // UnsubscribeBecausePermissionRevoked sometimes calls us with an empty one.
651 if (sender_id.empty()) { 764 if (sender_id.empty()) {
652 unregister_callback.Run(gcm::GCMClient::INVALID_PARAMETER); 765 unregister_callback.Run(gcm::GCMClient::INVALID_PARAMETER);
653 } else { 766 } else {
654 GetGCMDriver()->UnregisterWithSenderId( 767 GetGCMDriver()->UnregisterWithSenderId(
655 app_id, NormalizeSenderInfo(sender_id), unregister_callback); 768 app_id, NormalizeSenderInfo(sender_id), unregister_callback);
656 } 769 }
657 #else 770 #else
658 GetGCMDriver()->Unregister(app_id, unregister_callback); 771 GetGCMDriver()->Unregister(app_id, unregister_callback);
659 #endif 772 #endif
660 } 773 }
661 } 774 }
662 775
663 void PushMessagingServiceImpl::DidDeleteID( 776 void PushMessagingServiceImpl::DidDeleteID(
664 const std::string& app_id, 777 const std::string& app_id,
665 bool was_subscribed, 778 bool was_subscribed,
666 const content::PushMessagingService::UnregisterCallback& callback, 779 const content::PushMessagingService::UnregisterCallback& callback,
667 InstanceID::Result result) { 780 InstanceID::Result result) {
668 // DidUnsubscribeInstanceID must be run asynchronously, since it calls 781 // DidUnsubscribe must be run asynchronously when passing a non-empty
782 // |app_id_if_was_instance_id|, since it calls
669 // InstanceIDDriver::RemoveInstanceID which deletes the InstanceID itself. 783 // InstanceIDDriver::RemoveInstanceID which deletes the InstanceID itself.
670 // Calling that immediately would cause a use-after-free in our caller. 784 // Calling that immediately would cause a use-after-free in our caller.
671 base::ThreadTaskRunnerHandle::Get()->PostTask( 785 base::ThreadTaskRunnerHandle::Get()->PostTask(
672 FROM_HERE, base::Bind(&PushMessagingServiceImpl::DidUnsubscribeInstanceID, 786 FROM_HERE, base::Bind(&PushMessagingServiceImpl::DidUnsubscribe,
673 weak_factory_.GetWeakPtr(), app_id, was_subscribed, 787 weak_factory_.GetWeakPtr(), app_id, was_subscribed,
674 callback, result)); 788 callback, ToUnregisterStatus(result)));
675 } 789 }
676 790
677 void PushMessagingServiceImpl::DidUnsubscribeInstanceID( 791 void PushMessagingServiceImpl::DidUnsubscribe(
678 const std::string& app_id, 792 const std::string& app_id_if_was_instance_id,
679 bool was_subscribed, 793 bool was_subscribed,
680 const content::PushMessagingService::UnregisterCallback& callback, 794 const content::PushMessagingService::UnregisterCallback& callback,
681 InstanceID::Result result) { 795 content::PushUnregistrationStatus status) {
682 GetInstanceIDDriver()->RemoveInstanceID(app_id); 796 if (!app_id_if_was_instance_id.empty())
683 797 GetInstanceIDDriver()->RemoveInstanceID(app_id_if_was_instance_id);
684 if (was_subscribed)
685 DecreasePushSubscriptionCount(1, false /* was_pending */);
686 798
687 DCHECK(!callback.is_null()); 799 DCHECK(!callback.is_null());
688 800
689 if (!was_subscribed) { 801 if (was_subscribed) {
802 DecreasePushSubscriptionCount(1, false /* was_pending */);
803 callback.Run(status);
804 } else {
805 // Override status since there was no record of an existing subscription.
690 callback.Run( 806 callback.Run(
691 content::PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED); 807 content::PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED);
692 return;
693 }
694 switch (result) {
695 case InstanceID::SUCCESS:
696 callback.Run(content::PUSH_UNREGISTRATION_STATUS_SUCCESS_UNREGISTERED);
697 break;
698 case InstanceID::INVALID_PARAMETER:
699 case InstanceID::DISABLED:
700 case InstanceID::SERVER_ERROR:
701 case InstanceID::UNKNOWN_ERROR:
702 callback.Run(content::PUSH_UNREGISTRATION_STATUS_PENDING_SERVICE_ERROR);
703 break;
704 case InstanceID::ASYNC_OPERATION_PENDING:
705 case InstanceID::NETWORK_ERROR:
706 callback.Run(content::PUSH_UNREGISTRATION_STATUS_PENDING_NETWORK_ERROR);
707 break;
708 } 808 }
709 } 809 }
710 810
711 void PushMessagingServiceImpl::DidUnsubscribe(
712 bool was_subscribed,
713 const content::PushMessagingService::UnregisterCallback& callback,
714 gcm::GCMClient::Result gcm_result) {
715 if (was_subscribed)
716 DecreasePushSubscriptionCount(1, false /* was_pending */);
717
718 DCHECK(!callback.is_null());
719
720 if (!was_subscribed) {
721 callback.Run(
722 content::PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED);
723 return;
724 }
725 switch (gcm_result) {
726 case gcm::GCMClient::SUCCESS:
727 callback.Run(content::PUSH_UNREGISTRATION_STATUS_SUCCESS_UNREGISTERED);
728 break;
729 case gcm::GCMClient::INVALID_PARAMETER:
730 case gcm::GCMClient::GCM_DISABLED:
731 case gcm::GCMClient::SERVER_ERROR:
732 case gcm::GCMClient::UNKNOWN_ERROR:
733 callback.Run(content::PUSH_UNREGISTRATION_STATUS_PENDING_SERVICE_ERROR);
734 break;
735 case gcm::GCMClient::ASYNC_OPERATION_PENDING:
736 case gcm::GCMClient::NETWORK_ERROR:
737 case gcm::GCMClient::TTL_EXCEEDED:
738 callback.Run(content::PUSH_UNREGISTRATION_STATUS_PENDING_NETWORK_ERROR);
739 break;
740 }
741 }
742
743 // OnContentSettingChanged methods --------------------------------------------- 811 // OnContentSettingChanged methods ---------------------------------------------
744 812
745 void PushMessagingServiceImpl::OnContentSettingChanged( 813 void PushMessagingServiceImpl::OnContentSettingChanged(
746 const ContentSettingsPattern& primary_pattern, 814 const ContentSettingsPattern& primary_pattern,
747 const ContentSettingsPattern& secondary_pattern, 815 const ContentSettingsPattern& secondary_pattern,
748 ContentSettingsType content_type, 816 ContentSettingsType content_type,
749 std::string resource_identifier) { 817 std::string resource_identifier) {
750 if (content_type != CONTENT_SETTINGS_TYPE_NOTIFICATIONS) 818 if (content_type != CONTENT_SETTINGS_TYPE_NOTIFICATIONS)
751 return; 819 return;
752 820
(...skipping 27 matching lines...) Expand all
780 #if defined(OS_ANDROID) 848 #if defined(OS_ANDROID)
781 need_sender_id = 849 need_sender_id =
782 !PushMessagingAppIdentifier::UseInstanceID(app_identifier.app_id()); 850 !PushMessagingAppIdentifier::UseInstanceID(app_identifier.app_id());
783 #endif 851 #endif
784 if (need_sender_id) { 852 if (need_sender_id) {
785 GetSenderId( 853 GetSenderId(
786 profile_, app_identifier.origin(), 854 profile_, app_identifier.origin(),
787 app_identifier.service_worker_registration_id(), 855 app_identifier.service_worker_registration_id(),
788 base::Bind( 856 base::Bind(
789 &PushMessagingServiceImpl::UnsubscribeBecausePermissionRevoked, 857 &PushMessagingServiceImpl::UnsubscribeBecausePermissionRevoked,
790 weak_factory_.GetWeakPtr(), app_identifier, barrier_closure)); 858 weak_factory_.GetWeakPtr(), app_identifier,
859 base::Bind(&UnregisterCallbackToClosure, barrier_closure)));
791 } else { 860 } else {
792 UnsubscribeBecausePermissionRevoked( 861 UnsubscribeInternal(
793 app_identifier, barrier_closure, "" /* sender_id */, 862 content::PUSH_UNREGISTRATION_REASON_PERMISSION_REVOKED,
794 true /* success */, true /* not_found */); 863 app_identifier.origin(),
864 app_identifier.service_worker_registration_id(),
865 app_identifier.app_id(), std::string() /* sender_id */,
866 base::Bind(&UnregisterCallbackToClosure, barrier_closure));
795 } 867 }
796 } 868 }
797 } 869 }
798 870
799 void PushMessagingServiceImpl::UnsubscribeBecausePermissionRevoked( 871 void PushMessagingServiceImpl::UnsubscribeBecausePermissionRevoked(
800 const PushMessagingAppIdentifier& app_identifier, 872 const PushMessagingAppIdentifier& app_identifier,
801 const base::Closure& closure, 873 const content::PushMessagingService::UnregisterCallback& callback,
802 const std::string& sender_id, 874 const std::string& sender_id,
803 bool success, 875 bool success,
804 bool not_found) { 876 bool not_found) {
805 base::Closure barrier_closure = base::BarrierClosure(2, closure);
806
807 // Unsubscribe the PushMessagingAppIdentifier with the push service. 877 // Unsubscribe the PushMessagingAppIdentifier with the push service.
808 // It's possible for GetSenderId to have failed and sender_id to be empty, if 878 // It's possible for GetSenderId to have failed and sender_id to be empty, if
809 // cookies (and the SW database) for an origin got cleared before permissions 879 // cookies (and the SW database) for an origin got cleared before permissions
810 // are cleared for the origin. In that case for legacy GCM registrations on 880 // are cleared for the origin. In that case for legacy GCM registrations on
811 // Android, Unsubscribe will just delete the app identifier to block future 881 // Android, Unsubscribe will just delete the app identifier to block future
812 // messages. 882 // messages.
813 // TODO(johnme): Auto-unregister before SW DB is cleared 883 // TODO(johnme): Auto-unregister before SW DB is cleared (crbug.com/402458).
814 // (https://crbug.com/402458). 884 UnsubscribeInternal(content::PUSH_UNREGISTRATION_REASON_PERMISSION_REVOKED,
815 Unsubscribe(app_identifier.app_id(), sender_id, 885 app_identifier.origin(),
816 base::Bind(&UnregisterCallbackToClosure, barrier_closure)); 886 app_identifier.service_worker_registration_id(),
817 887 app_identifier.app_id(), sender_id, callback);
818 // Clear the associated service worker push registration id.
819 ClearPushSubscriptionID(profile_, app_identifier.origin(),
820 app_identifier.service_worker_registration_id(),
821 barrier_closure);
822 } 888 }
823 889
824 void PushMessagingServiceImpl::SetContentSettingChangedCallbackForTesting( 890 void PushMessagingServiceImpl::SetContentSettingChangedCallbackForTesting(
825 const base::Closure& callback) { 891 const base::Closure& callback) {
826 content_setting_changed_callback_for_testing_ = callback; 892 content_setting_changed_callback_for_testing_ = callback;
827 } 893 }
828 894
829 // KeyedService methods ------------------------------------------------------- 895 // KeyedService methods -------------------------------------------------------
830 896
831 void PushMessagingServiceImpl::Shutdown() { 897 void PushMessagingServiceImpl::Shutdown() {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
893 } 959 }
894 960
895 instance_id::InstanceIDDriver* PushMessagingServiceImpl::GetInstanceIDDriver() 961 instance_id::InstanceIDDriver* PushMessagingServiceImpl::GetInstanceIDDriver()
896 const { 962 const {
897 instance_id::InstanceIDProfileService* instance_id_profile_service = 963 instance_id::InstanceIDProfileService* instance_id_profile_service =
898 instance_id::InstanceIDProfileServiceFactory::GetForProfile(profile_); 964 instance_id::InstanceIDProfileServiceFactory::GetForProfile(profile_);
899 CHECK(instance_id_profile_service); 965 CHECK(instance_id_profile_service);
900 CHECK(instance_id_profile_service->driver()); 966 CHECK(instance_id_profile_service->driver());
901 return instance_id_profile_service->driver(); 967 return instance_id_profile_service->driver();
902 } 968 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698