OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |