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

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: Added enum reuse comments 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:
96 NOTREACHED();
97 return blink::WebPushPermissionStatusDenied;
98 } 100 }
101 NOTREACHED();
102 return blink::WebPushPermissionStatusDenied;
103 }
104
105 content::PushUnregistrationStatus ToUnregisterStatus(
106 InstanceID::Result result) {
107 switch (result) {
108 case InstanceID::SUCCESS:
109 return content::PUSH_UNREGISTRATION_STATUS_SUCCESS_UNREGISTERED;
110 case InstanceID::INVALID_PARAMETER:
111 case InstanceID::DISABLED:
112 case InstanceID::SERVER_ERROR:
113 case InstanceID::UNKNOWN_ERROR:
114 return content::PUSH_UNREGISTRATION_STATUS_PENDING_SERVICE_ERROR;
115 case InstanceID::ASYNC_OPERATION_PENDING:
116 case InstanceID::NETWORK_ERROR:
117 return content::PUSH_UNREGISTRATION_STATUS_PENDING_NETWORK_ERROR;
118 }
119 NOTREACHED();
120 return content::PUSH_UNREGISTRATION_STATUS_SERVICE_NOT_AVAILABLE;
121 }
122
123 content::PushUnregistrationStatus ToUnregisterStatus(
124 gcm::GCMClient::Result gcm_result) {
125 switch (gcm_result) {
126 case gcm::GCMClient::SUCCESS:
127 return content::PUSH_UNREGISTRATION_STATUS_SUCCESS_UNREGISTERED;
128 case gcm::GCMClient::INVALID_PARAMETER:
129 case gcm::GCMClient::GCM_DISABLED:
130 case gcm::GCMClient::SERVER_ERROR:
131 case gcm::GCMClient::UNKNOWN_ERROR:
132 return content::PUSH_UNREGISTRATION_STATUS_PENDING_SERVICE_ERROR;
133 case gcm::GCMClient::ASYNC_OPERATION_PENDING:
134 case gcm::GCMClient::NETWORK_ERROR:
135 case gcm::GCMClient::TTL_EXCEEDED:
136 return content::PUSH_UNREGISTRATION_STATUS_PENDING_NETWORK_ERROR;
137 }
138 NOTREACHED();
139 return content::PUSH_UNREGISTRATION_STATUS_SERVICE_NOT_AVAILABLE;
140 }
141
142 void GCMCallbackToUnregisterCallback(
143 const content::PushMessagingService::UnregisterCallback& callback,
144 gcm::GCMClient::Result result) {
145 DCHECK(!callback.is_null());
146 callback.Run(ToUnregisterStatus(result));
99 } 147 }
100 148
101 void UnregisterCallbackToClosure(const base::Closure& closure, 149 void UnregisterCallbackToClosure(const base::Closure& closure,
102 content::PushUnregistrationStatus status) { 150 content::PushUnregistrationStatus status) {
151 DCHECK(!closure.is_null());
103 closure.Run(); 152 closure.Run();
104 } 153 }
105 154
106 #if BUILDFLAG(ENABLE_BACKGROUND) 155 #if BUILDFLAG(ENABLE_BACKGROUND)
107 bool UseBackgroundMode() { 156 bool UseBackgroundMode() {
108 // Note: if push is ever enabled in incognito, the background mode integration 157 // Note: if push is ever enabled in incognito, the background mode integration
109 // should not be enabled for it. 158 // should not be enabled for it.
110 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); 159 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
111 if (command_line->HasSwitch(switches::kDisablePushApiBackgroundMode)) 160 if (command_line->HasSwitch(switches::kDisablePushApiBackgroundMode))
112 return false; 161 return false;
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 } 278 }
230 #endif 279 #endif
231 280
232 base::Closure message_handled_closure = 281 base::Closure message_handled_closure =
233 message_callback_for_testing_.is_null() ? base::Bind(&base::DoNothing) 282 message_callback_for_testing_.is_null() ? base::Bind(&base::DoNothing)
234 : message_callback_for_testing_; 283 : message_callback_for_testing_;
235 PushMessagingAppIdentifier app_identifier = 284 PushMessagingAppIdentifier app_identifier =
236 PushMessagingAppIdentifier::FindByAppId(profile_, app_id); 285 PushMessagingAppIdentifier::FindByAppId(profile_, app_id);
237 // Drop message and unregister if app_id was unknown (maybe recently deleted). 286 // Drop message and unregister if app_id was unknown (maybe recently deleted).
238 if (app_identifier.is_null()) { 287 if (app_identifier.is_null()) {
239 DeliverMessageCallback(app_id, GURL::EmptyGURL(), -1, message, 288 DeliverMessageCallback(app_id, GURL::EmptyGURL(),
240 message_handled_closure, 289 -1 /* kInvalidServiceWorkerRegistrationId */,
290 message, message_handled_closure,
241 content::PUSH_DELIVERY_STATUS_UNKNOWN_APP_ID); 291 content::PUSH_DELIVERY_STATUS_UNKNOWN_APP_ID);
242 return; 292 return;
243 } 293 }
244 // Drop message and unregister if |origin| has lost push permission. 294 // Drop message and unregister if |origin| has lost push permission.
245 if (!IsPermissionSet(app_identifier.origin())) { 295 if (!IsPermissionSet(app_identifier.origin())) {
246 DeliverMessageCallback(app_id, app_identifier.origin(), 296 DeliverMessageCallback(app_id, app_identifier.origin(),
247 app_identifier.service_worker_registration_id(), 297 app_identifier.service_worker_registration_id(),
248 message, message_handled_closure, 298 message, message_handled_closure,
249 content::PUSH_DELIVERY_STATUS_PERMISSION_DENIED); 299 content::PUSH_DELIVERY_STATUS_PERMISSION_DENIED);
250 return; 300 return;
(...skipping 29 matching lines...) Expand all
280 330
281 void PushMessagingServiceImpl::DeliverMessageCallback( 331 void PushMessagingServiceImpl::DeliverMessageCallback(
282 const std::string& app_id, 332 const std::string& app_id,
283 const GURL& requesting_origin, 333 const GURL& requesting_origin,
284 int64_t service_worker_registration_id, 334 int64_t service_worker_registration_id,
285 const gcm::IncomingMessage& message, 335 const gcm::IncomingMessage& message,
286 const base::Closure& message_handled_closure, 336 const base::Closure& message_handled_closure,
287 content::PushDeliveryStatus status) { 337 content::PushDeliveryStatus status) {
288 DCHECK_GE(in_flight_message_deliveries_.count(app_id), 1u); 338 DCHECK_GE(in_flight_message_deliveries_.count(app_id), 1u);
289 339
340 RecordDeliveryStatus(status);
341
290 base::Closure completion_closure = 342 base::Closure completion_closure =
291 base::Bind(&PushMessagingServiceImpl::DidHandleMessage, 343 base::Bind(&PushMessagingServiceImpl::DidHandleMessage,
292 weak_factory_.GetWeakPtr(), app_id, message_handled_closure); 344 weak_factory_.GetWeakPtr(), app_id, message_handled_closure);
293 // The completion_closure should run by default at the end of this function, 345 // The completion_closure should run by default at the end of this function,
294 // unless it is explicitly passed to another function. 346 // unless it is explicitly passed to another function.
295 base::ScopedClosureRunner completion_closure_runner(completion_closure); 347 base::ScopedClosureRunner completion_closure_runner(completion_closure);
296 348
349 // A reason to automatically unsubscribe. UNKNOWN means do not unsubscribe.
350 content::PushUnregistrationReason unsubscribe_reason =
351 content::PUSH_UNREGISTRATION_REASON_UNKNOWN;
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 != content::PUSH_UNREGISTRATION_REASON_UNKNOWN) {
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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 } 458 }
385 459
386 // Subscribe and GetPermissionStatus methods ----------------------------------- 460 // Subscribe and GetPermissionStatus methods -----------------------------------
387 461
388 void PushMessagingServiceImpl::SubscribeFromDocument( 462 void PushMessagingServiceImpl::SubscribeFromDocument(
389 const GURL& requesting_origin, 463 const GURL& requesting_origin,
390 int64_t service_worker_registration_id, 464 int64_t service_worker_registration_id,
391 int renderer_id, 465 int renderer_id,
392 int render_frame_id, 466 int render_frame_id,
393 const content::PushSubscriptionOptions& options, 467 const content::PushSubscriptionOptions& options,
394 const content::PushMessagingService::RegisterCallback& callback) { 468 const RegisterCallback& callback) {
395 PushMessagingAppIdentifier app_identifier = 469 PushMessagingAppIdentifier app_identifier =
396 PushMessagingAppIdentifier::Generate(requesting_origin, 470 PushMessagingAppIdentifier::Generate(requesting_origin,
397 service_worker_registration_id); 471 service_worker_registration_id);
398 472
399 if (push_subscription_count_ + pending_push_subscription_count_ >= 473 if (push_subscription_count_ + pending_push_subscription_count_ >=
400 kMaxRegistrations) { 474 kMaxRegistrations) {
401 SubscribeEndWithError(callback, 475 SubscribeEndWithError(callback,
402 content::PUSH_REGISTRATION_STATUS_LIMIT_REACHED); 476 content::PUSH_REGISTRATION_STATUS_LIMIT_REACHED);
403 return; 477 return;
404 } 478 }
(...skipping 20 matching lines...) Expand all
425 requesting_origin, true /* user_gesture */, 499 requesting_origin, true /* user_gesture */,
426 base::Bind(&PushMessagingServiceImpl::DoSubscribe, 500 base::Bind(&PushMessagingServiceImpl::DoSubscribe,
427 weak_factory_.GetWeakPtr(), app_identifier, options, 501 weak_factory_.GetWeakPtr(), app_identifier, options,
428 callback)); 502 callback));
429 } 503 }
430 504
431 void PushMessagingServiceImpl::SubscribeFromWorker( 505 void PushMessagingServiceImpl::SubscribeFromWorker(
432 const GURL& requesting_origin, 506 const GURL& requesting_origin,
433 int64_t service_worker_registration_id, 507 int64_t service_worker_registration_id,
434 const content::PushSubscriptionOptions& options, 508 const content::PushSubscriptionOptions& options,
435 const content::PushMessagingService::RegisterCallback& register_callback) { 509 const RegisterCallback& register_callback) {
436 PushMessagingAppIdentifier app_identifier = 510 PushMessagingAppIdentifier app_identifier =
437 PushMessagingAppIdentifier::Generate(requesting_origin, 511 PushMessagingAppIdentifier::Generate(requesting_origin,
438 service_worker_registration_id); 512 service_worker_registration_id);
439 513
440 if (push_subscription_count_ + pending_push_subscription_count_ >= 514 if (push_subscription_count_ + pending_push_subscription_count_ >=
441 kMaxRegistrations) { 515 kMaxRegistrations) {
442 SubscribeEndWithError(register_callback, 516 SubscribeEndWithError(register_callback,
443 content::PUSH_REGISTRATION_STATUS_LIMIT_REACHED); 517 content::PUSH_REGISTRATION_STATUS_LIMIT_REACHED);
444 return; 518 return;
445 } 519 }
(...skipping 24 matching lines...) Expand all
470 content::PermissionType::PUSH_MESSAGING, origin, origin)); 544 content::PermissionType::PUSH_MESSAGING, origin, origin));
471 } 545 }
472 546
473 bool PushMessagingServiceImpl::SupportNonVisibleMessages() { 547 bool PushMessagingServiceImpl::SupportNonVisibleMessages() {
474 return false; 548 return false;
475 } 549 }
476 550
477 void PushMessagingServiceImpl::DoSubscribe( 551 void PushMessagingServiceImpl::DoSubscribe(
478 const PushMessagingAppIdentifier& app_identifier, 552 const PushMessagingAppIdentifier& app_identifier,
479 const content::PushSubscriptionOptions& options, 553 const content::PushSubscriptionOptions& options,
480 const content::PushMessagingService::RegisterCallback& register_callback, 554 const RegisterCallback& register_callback,
481 blink::mojom::PermissionStatus permission_status) { 555 blink::mojom::PermissionStatus permission_status) {
482 if (permission_status != blink::mojom::PermissionStatus::GRANTED) { 556 if (permission_status != blink::mojom::PermissionStatus::GRANTED) {
483 SubscribeEndWithError(register_callback, 557 SubscribeEndWithError(register_callback,
484 content::PUSH_REGISTRATION_STATUS_PERMISSION_DENIED); 558 content::PUSH_REGISTRATION_STATUS_PERMISSION_DENIED);
485 return; 559 return;
486 } 560 }
487 561
488 IncreasePushSubscriptionCount(1, true /* is_pending */); 562 IncreasePushSubscriptionCount(1, true /* is_pending */);
489 563
490 GetInstanceIDDriver() 564 GetInstanceIDDriver()
491 ->GetInstanceID(app_identifier.app_id()) 565 ->GetInstanceID(app_identifier.app_id())
492 ->GetToken(NormalizeSenderInfo(options.sender_info), kGCMScope, 566 ->GetToken(NormalizeSenderInfo(options.sender_info), kGCMScope,
493 std::map<std::string, std::string>() /* options */, 567 std::map<std::string, std::string>() /* options */,
494 base::Bind(&PushMessagingServiceImpl::DidSubscribe, 568 base::Bind(&PushMessagingServiceImpl::DidSubscribe,
495 weak_factory_.GetWeakPtr(), app_identifier, 569 weak_factory_.GetWeakPtr(), app_identifier,
496 options.sender_info, register_callback)); 570 options.sender_info, register_callback));
497 } 571 }
498 572
499 void PushMessagingServiceImpl::SubscribeEnd( 573 void PushMessagingServiceImpl::SubscribeEnd(
500 const content::PushMessagingService::RegisterCallback& callback, 574 const RegisterCallback& callback,
501 const std::string& subscription_id, 575 const std::string& subscription_id,
502 const std::vector<uint8_t>& p256dh, 576 const std::vector<uint8_t>& p256dh,
503 const std::vector<uint8_t>& auth, 577 const std::vector<uint8_t>& auth,
504 content::PushRegistrationStatus status) { 578 content::PushRegistrationStatus status) {
505 callback.Run(subscription_id, p256dh, auth, status); 579 callback.Run(subscription_id, p256dh, auth, status);
506 } 580 }
507 581
508 void PushMessagingServiceImpl::SubscribeEndWithError( 582 void PushMessagingServiceImpl::SubscribeEndWithError(
509 const content::PushMessagingService::RegisterCallback& callback, 583 const RegisterCallback& callback,
510 content::PushRegistrationStatus status) { 584 content::PushRegistrationStatus status) {
511 SubscribeEnd(callback, std::string() /* subscription_id */, 585 SubscribeEnd(callback, std::string() /* subscription_id */,
512 std::vector<uint8_t>() /* p256dh */, 586 std::vector<uint8_t>() /* p256dh */,
513 std::vector<uint8_t>() /* auth */, status); 587 std::vector<uint8_t>() /* auth */, status);
514 } 588 }
515 589
516 void PushMessagingServiceImpl::DidSubscribe( 590 void PushMessagingServiceImpl::DidSubscribe(
517 const PushMessagingAppIdentifier& app_identifier, 591 const PushMessagingAppIdentifier& app_identifier,
518 const std::string& sender_id, 592 const std::string& sender_id,
519 const content::PushMessagingService::RegisterCallback& callback, 593 const RegisterCallback& callback,
520 const std::string& subscription_id, 594 const std::string& subscription_id,
521 InstanceID::Result result) { 595 InstanceID::Result result) {
522 DecreasePushSubscriptionCount(1, true /* was_pending */); 596 DecreasePushSubscriptionCount(1, true /* was_pending */);
523 597
524 content::PushRegistrationStatus status = 598 content::PushRegistrationStatus status =
525 content::PUSH_REGISTRATION_STATUS_SERVICE_ERROR; 599 content::PUSH_REGISTRATION_STATUS_SERVICE_ERROR;
526 600
527 switch (result) { 601 switch (result) {
528 case InstanceID::SUCCESS: 602 case InstanceID::SUCCESS:
529 // Make sure that this subscription has associated encryption keys prior 603 // Make sure that this subscription has associated encryption keys prior
(...skipping 17 matching lines...) Expand all
547 case InstanceID::NETWORK_ERROR: 621 case InstanceID::NETWORK_ERROR:
548 status = content::PUSH_REGISTRATION_STATUS_NETWORK_ERROR; 622 status = content::PUSH_REGISTRATION_STATUS_NETWORK_ERROR;
549 break; 623 break;
550 } 624 }
551 625
552 SubscribeEndWithError(callback, status); 626 SubscribeEndWithError(callback, status);
553 } 627 }
554 628
555 void PushMessagingServiceImpl::DidSubscribeWithEncryptionInfo( 629 void PushMessagingServiceImpl::DidSubscribeWithEncryptionInfo(
556 const PushMessagingAppIdentifier& app_identifier, 630 const PushMessagingAppIdentifier& app_identifier,
557 const content::PushMessagingService::RegisterCallback& callback, 631 const RegisterCallback& callback,
558 const std::string& subscription_id, 632 const std::string& subscription_id,
559 const std::string& p256dh, 633 const std::string& p256dh,
560 const std::string& auth_secret) { 634 const std::string& auth_secret) {
561 if (p256dh.empty()) { 635 if (p256dh.empty()) {
562 SubscribeEndWithError( 636 SubscribeEndWithError(
563 callback, content::PUSH_REGISTRATION_STATUS_PUBLIC_KEY_UNAVAILABLE); 637 callback, content::PUSH_REGISTRATION_STATUS_PUBLIC_KEY_UNAVAILABLE);
564 return; 638 return;
565 } 639 }
566 640
567 app_identifier.PersistToPrefs(profile_); 641 app_identifier.PersistToPrefs(profile_);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 callback.Run(success, std::vector<uint8_t>(p256dh.begin(), p256dh.end()), 677 callback.Run(success, std::vector<uint8_t>(p256dh.begin(), p256dh.end()),
604 std::vector<uint8_t>(auth_secret.begin(), auth_secret.end())); 678 std::vector<uint8_t>(auth_secret.begin(), auth_secret.end()));
605 } 679 }
606 680
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 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 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 UnregisterCallback& callback) {
732 if (app_id.empty()) {
733 // Without an |app_id|, we can neither delete the subscription from the
734 // PushMessagingAppIdentifier map, nor unsubscribe with the GCM Driver.
618 callback.Run( 735 callback.Run(
619 content::PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED); 736 content::PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED);
620 return; 737 return;
621 } 738 }
622 739
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 740 // Delete the mapping for this app_id, to guarantee that no messages get
631 // delivered in future (even if unregistration fails). 741 // delivered in future (even if unregistration fails).
632 // TODO(johnme): Instead of deleting these app ids, store them elsewhere, and 742 // 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). 743 // retry unregistration if it fails due to network errors (crbug.com/465399).
634 PushMessagingAppIdentifier app_identifier = 744 PushMessagingAppIdentifier app_identifier =
635 PushMessagingAppIdentifier::FindByAppId(profile_, app_id); 745 PushMessagingAppIdentifier::FindByAppId(profile_, app_id);
636 bool was_subscribed = !app_identifier.is_null(); 746 bool was_subscribed = !app_identifier.is_null();
637 if (was_subscribed) 747 if (was_subscribed)
638 app_identifier.DeleteFromPrefs(profile_); 748 app_identifier.DeleteFromPrefs(profile_);
639 749
640 if (PushMessagingAppIdentifier::UseInstanceID(app_id)) { 750 if (PushMessagingAppIdentifier::UseInstanceID(app_id)) {
641 GetInstanceIDDriver()->GetInstanceID(app_id)->DeleteID(base::Bind( 751 GetInstanceIDDriver()->GetInstanceID(app_id)->DeleteID(base::Bind(
642 &PushMessagingServiceImpl::DidDeleteID, weak_factory_.GetWeakPtr(), 752 &PushMessagingServiceImpl::DidDeleteID, weak_factory_.GetWeakPtr(),
643 app_id, was_subscribed, callback)); 753 app_id, was_subscribed, callback));
754
644 } else { 755 } else {
645 auto unregister_callback = 756 auto unregister_callback =
646 base::Bind(&PushMessagingServiceImpl::DidUnsubscribe, 757 base::Bind(&GCMCallbackToUnregisterCallback,
647 weak_factory_.GetWeakPtr(), was_subscribed, callback); 758 base::Bind(&PushMessagingServiceImpl::DidUnsubscribe,
759 weak_factory_.GetWeakPtr(),
760 std::string() /* app_id_when_instance_id */,
761 was_subscribed, callback));
648 #if defined(OS_ANDROID) 762 #if defined(OS_ANDROID)
649 // On Android the backend is different, and requires the original sender_id. 763 // On Android the backend is different, and requires the original sender_id.
650 // UnsubscribeBecausePermissionRevoked sometimes calls us with an empty one. 764 // UnsubscribeBecausePermissionRevoked sometimes calls us with an empty one.
651 if (sender_id.empty()) { 765 if (sender_id.empty()) {
652 unregister_callback.Run(gcm::GCMClient::INVALID_PARAMETER); 766 unregister_callback.Run(gcm::GCMClient::INVALID_PARAMETER);
653 } else { 767 } else {
654 GetGCMDriver()->UnregisterWithSenderId( 768 GetGCMDriver()->UnregisterWithSenderId(
655 app_id, NormalizeSenderInfo(sender_id), unregister_callback); 769 app_id, NormalizeSenderInfo(sender_id), unregister_callback);
656 } 770 }
657 #else 771 #else
658 GetGCMDriver()->Unregister(app_id, unregister_callback); 772 GetGCMDriver()->Unregister(app_id, unregister_callback);
659 #endif 773 #endif
660 } 774 }
661 } 775 }
662 776
663 void PushMessagingServiceImpl::DidDeleteID( 777 void PushMessagingServiceImpl::DidDeleteID(const std::string& app_id,
664 const std::string& app_id, 778 bool was_subscribed,
665 bool was_subscribed, 779 const UnregisterCallback& callback,
666 const content::PushMessagingService::UnregisterCallback& callback, 780 InstanceID::Result result) {
667 InstanceID::Result result) { 781 // DidUnsubscribe must be run asynchronously when passing a non-empty
668 // DidUnsubscribeInstanceID must be run asynchronously, since it calls 782 // |app_id_when_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_when_instance_id,
679 bool was_subscribed, 793 bool was_subscribed,
680 const content::PushMessagingService::UnregisterCallback& callback, 794 const UnregisterCallback& callback,
681 InstanceID::Result result) { 795 content::PushUnregistrationStatus status) {
682 GetInstanceIDDriver()->RemoveInstanceID(app_id); 796 if (!app_id_when_instance_id.empty())
683 797 GetInstanceIDDriver()->RemoveInstanceID(app_id_when_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 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
« no previous file with comments | « chrome/browser/push_messaging/push_messaging_service_impl.h ('k') | chrome/test/data/push_messaging/push_test.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698