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

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

Issue 1851423003: Make Web Push use InstanceID tokens instead of GCM registrations (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@iid4default
Patch Set: Rebase Created 4 years, 3 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"
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/bind_helpers.h" 12 #include "base/bind_helpers.h"
13 #include "base/callback_helpers.h" 13 #include "base/callback_helpers.h"
14 #include "base/command_line.h" 14 #include "base/command_line.h"
15 #include "base/feature_list.h" 15 #include "base/feature_list.h"
16 #include "base/logging.h" 16 #include "base/logging.h"
17 #include "base/metrics/histogram_macros.h" 17 #include "base/metrics/histogram_macros.h"
18 #include "base/strings/string_util.h"
18 #include "build/build_config.h" 19 #include "build/build_config.h"
19 #include "chrome/browser/browser_process.h" 20 #include "chrome/browser/browser_process.h"
20 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" 21 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
21 #include "chrome/browser/permissions/permission_manager.h" 22 #include "chrome/browser/permissions/permission_manager.h"
22 #include "chrome/browser/profiles/profile.h" 23 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/browser/push_messaging/push_messaging_app_identifier.h" 24 #include "chrome/browser/push_messaging/push_messaging_app_identifier.h"
24 #include "chrome/browser/push_messaging/push_messaging_constants.h" 25 #include "chrome/browser/push_messaging/push_messaging_constants.h"
25 #include "chrome/browser/push_messaging/push_messaging_service_factory.h" 26 #include "chrome/browser/push_messaging/push_messaging_service_factory.h"
26 #include "chrome/browser/push_messaging/push_messaging_service_observer.h" 27 #include "chrome/browser/push_messaging/push_messaging_service_observer.h"
27 #include "chrome/browser/services/gcm/gcm_profile_service_factory.h" 28 #include "chrome/browser/services/gcm/gcm_profile_service_factory.h"
29 #include "chrome/browser/services/gcm/instance_id/instance_id_profile_service.h"
30 #include "chrome/browser/services/gcm/instance_id/instance_id_profile_service_fa ctory.h"
28 #include "chrome/browser/ui/chrome_pages.h" 31 #include "chrome/browser/ui/chrome_pages.h"
29 #include "chrome/common/chrome_features.h" 32 #include "chrome/common/chrome_features.h"
30 #include "chrome/common/chrome_switches.h" 33 #include "chrome/common/chrome_switches.h"
31 #include "chrome/common/features.h" 34 #include "chrome/common/features.h"
32 #include "chrome/common/pref_names.h" 35 #include "chrome/common/pref_names.h"
33 #include "chrome/grit/generated_resources.h" 36 #include "chrome/grit/generated_resources.h"
34 #include "components/content_settings/core/browser/host_content_settings_map.h" 37 #include "components/content_settings/core/browser/host_content_settings_map.h"
35 #include "components/gcm_driver/gcm_driver.h" 38 #include "components/gcm_driver/gcm_driver.h"
36 #include "components/gcm_driver/gcm_profile_service.h" 39 #include "components/gcm_driver/gcm_profile_service.h"
40 #include "components/gcm_driver/instance_id/instance_id.h"
41 #include "components/gcm_driver/instance_id/instance_id_driver.h"
37 #include "components/pref_registry/pref_registry_syncable.h" 42 #include "components/pref_registry/pref_registry_syncable.h"
38 #include "components/prefs/pref_service.h" 43 #include "components/prefs/pref_service.h"
39 #include "components/rappor/rappor_utils.h" 44 #include "components/rappor/rappor_utils.h"
40 #include "content/public/browser/browser_context.h" 45 #include "content/public/browser/browser_context.h"
41 #include "content/public/browser/permission_type.h" 46 #include "content/public/browser/permission_type.h"
42 #include "content/public/browser/render_frame_host.h" 47 #include "content/public/browser/render_frame_host.h"
43 #include "content/public/browser/service_worker_context.h" 48 #include "content/public/browser/service_worker_context.h"
44 #include "content/public/browser/storage_partition.h" 49 #include "content/public/browser/storage_partition.h"
45 #include "content/public/browser/web_contents.h" 50 #include "content/public/browser/web_contents.h"
46 #include "content/public/common/child_process_host.h" 51 #include "content/public/common/child_process_host.h"
47 #include "content/public/common/content_switches.h" 52 #include "content/public/common/content_switches.h"
48 #include "content/public/common/push_messaging_status.h" 53 #include "content/public/common/push_messaging_status.h"
49 #include "content/public/common/push_subscription_options.h" 54 #include "content/public/common/push_subscription_options.h"
50 #include "ui/base/l10n/l10n_util.h" 55 #include "ui/base/l10n/l10n_util.h"
51 56
52 #if BUILDFLAG(ENABLE_BACKGROUND) 57 #if BUILDFLAG(ENABLE_BACKGROUND)
53 #include "chrome/browser/background/background_mode_manager.h" 58 #include "chrome/browser/background/background_mode_manager.h"
54 #include "chrome/browser/lifetime/keep_alive_types.h" 59 #include "chrome/browser/lifetime/keep_alive_types.h"
55 #include "chrome/browser/lifetime/scoped_keep_alive.h" 60 #include "chrome/browser/lifetime/scoped_keep_alive.h"
56 #endif 61 #endif
57 62
63 using instance_id::InstanceID;
64
58 namespace { 65 namespace {
66
67 // Scope passed to getToken to obtain GCM registration tokens.
68 // Must match Java GoogleCloudMessaging.INSTANCE_ID_SCOPE.
69 const char kGCMScope[] = "GCM";
70
59 const int kMaxRegistrations = 1000000; 71 const int kMaxRegistrations = 1000000;
60 72
61 // Chrome does not yet support silent push messages, and requires websites to 73 // Chrome does not yet support silent push messages, and requires websites to
62 // indicate that they will only send user-visible messages. 74 // indicate that they will only send user-visible messages.
63 const char kSilentPushUnsupportedMessage[] = 75 const char kSilentPushUnsupportedMessage[] =
64 "Chrome currently only supports the Push API for subscriptions that will " 76 "Chrome currently only supports the Push API for subscriptions that will "
65 "result in user-visible messages. You can indicate this by calling " 77 "result in user-visible messages. You can indicate this by calling "
66 "pushManager.subscribe({userVisibleOnly: true}) instead. See " 78 "pushManager.subscribe({userVisibleOnly: true}) instead. See "
67 "https://goo.gl/yqv4Q4 for more details."; 79 "https://goo.gl/yqv4Q4 for more details.";
68 80
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 #if BUILDFLAG(ENABLE_BACKGROUND) 186 #if BUILDFLAG(ENABLE_BACKGROUND)
175 if (UseBackgroundMode() && g_browser_process->background_mode_manager()) { 187 if (UseBackgroundMode() && g_browser_process->background_mode_manager()) {
176 g_browser_process->background_mode_manager()->UnregisterTrigger(profile_, 188 g_browser_process->background_mode_manager()->UnregisterTrigger(profile_,
177 this); 189 this);
178 } 190 }
179 #endif // BUILDFLAG(ENABLE_BACKGROUND) 191 #endif // BUILDFLAG(ENABLE_BACKGROUND)
180 } 192 }
181 } 193 }
182 194
183 bool PushMessagingServiceImpl::CanHandle(const std::string& app_id) const { 195 bool PushMessagingServiceImpl::CanHandle(const std::string& app_id) const {
184 return !PushMessagingAppIdentifier::FindByAppId(profile_, app_id).is_null(); 196 return base::StartsWith(app_id, kPushMessagingAppIdentifierPrefix,
197 base::CompareCase::INSENSITIVE_ASCII);
185 } 198 }
186 199
187 void PushMessagingServiceImpl::ShutdownHandler() { 200 void PushMessagingServiceImpl::ShutdownHandler() {
188 // Shutdown() should come before and it removes us from the list of app 201 // Shutdown() should come before and it removes us from the list of app
189 // handlers of gcm::GCMDriver so this shouldn't ever been called. 202 // handlers of gcm::GCMDriver so this shouldn't ever been called.
190 NOTREACHED(); 203 NOTREACHED();
191 } 204 }
192 205
193 // OnMessage methods ----------------------------------------------------------- 206 // OnMessage methods -----------------------------------------------------------
194 207
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 414
402 SubscribeEndWithError(callback, 415 SubscribeEndWithError(callback,
403 content::PUSH_REGISTRATION_STATUS_PERMISSION_DENIED); 416 content::PUSH_REGISTRATION_STATUS_PERMISSION_DENIED);
404 return; 417 return;
405 } 418 }
406 419
407 // Push does not allow permission requests from iframes. 420 // Push does not allow permission requests from iframes.
408 profile_->GetPermissionManager()->RequestPermission( 421 profile_->GetPermissionManager()->RequestPermission(
409 content::PermissionType::PUSH_MESSAGING, web_contents->GetMainFrame(), 422 content::PermissionType::PUSH_MESSAGING, web_contents->GetMainFrame(),
410 requesting_origin, true /* user_gesture */, 423 requesting_origin, true /* user_gesture */,
411 base::Bind(&PushMessagingServiceImpl::DidRequestPermission, 424 base::Bind(&PushMessagingServiceImpl::DoSubscribe,
412 weak_factory_.GetWeakPtr(), app_identifier, options, 425 weak_factory_.GetWeakPtr(), app_identifier, options,
413 callback)); 426 callback));
414 } 427 }
415 428
416 void PushMessagingServiceImpl::SubscribeFromWorker( 429 void PushMessagingServiceImpl::SubscribeFromWorker(
417 const GURL& requesting_origin, 430 const GURL& requesting_origin,
418 int64_t service_worker_registration_id, 431 int64_t service_worker_registration_id,
419 const content::PushSubscriptionOptions& options, 432 const content::PushSubscriptionOptions& options,
420 const content::PushMessagingService::RegisterCallback& register_callback) { 433 const content::PushMessagingService::RegisterCallback& register_callback) {
421 PushMessagingAppIdentifier app_identifier = 434 PushMessagingAppIdentifier app_identifier =
422 PushMessagingAppIdentifier::Generate(requesting_origin, 435 PushMessagingAppIdentifier::Generate(requesting_origin,
423 service_worker_registration_id); 436 service_worker_registration_id);
424 437
425 if (push_subscription_count_ + pending_push_subscription_count_ >= 438 if (push_subscription_count_ + pending_push_subscription_count_ >=
426 kMaxRegistrations) { 439 kMaxRegistrations) {
427 SubscribeEndWithError(register_callback, 440 SubscribeEndWithError(register_callback,
428 content::PUSH_REGISTRATION_STATUS_LIMIT_REACHED); 441 content::PUSH_REGISTRATION_STATUS_LIMIT_REACHED);
429 return; 442 return;
430 } 443 }
431 444
432 blink::WebPushPermissionStatus permission_status = 445 blink::WebPushPermissionStatus permission_status =
433 PushMessagingServiceImpl::GetPermissionStatus(requesting_origin, 446 GetPermissionStatus(requesting_origin, options.user_visible_only);
434 options.user_visible_only);
435 447
436 if (permission_status != blink::WebPushPermissionStatusGranted) { 448 if (permission_status != blink::WebPushPermissionStatusGranted) {
437 SubscribeEndWithError(register_callback, 449 SubscribeEndWithError(register_callback,
438 content::PUSH_REGISTRATION_STATUS_PERMISSION_DENIED); 450 content::PUSH_REGISTRATION_STATUS_PERMISSION_DENIED);
439 return; 451 return;
440 } 452 }
441 453
442 IncreasePushSubscriptionCount(1, true /* is_pending */); 454 DoSubscribe(app_identifier, options, register_callback,
443 std::vector<std::string> sender_ids(1, 455 blink::mojom::PermissionStatus::GRANTED);
444 NormalizeSenderInfo(options.sender_info));
445
446 GetGCMDriver()->Register(app_identifier.app_id(), sender_ids,
447 base::Bind(&PushMessagingServiceImpl::DidSubscribe,
448 weak_factory_.GetWeakPtr(),
449 app_identifier, register_callback));
450 } 456 }
451 457
452 blink::WebPushPermissionStatus PushMessagingServiceImpl::GetPermissionStatus( 458 blink::WebPushPermissionStatus PushMessagingServiceImpl::GetPermissionStatus(
453 const GURL& origin, 459 const GURL& origin,
454 bool user_visible) { 460 bool user_visible) {
455 if (!user_visible) 461 if (!user_visible)
456 return blink::WebPushPermissionStatusDenied; 462 return blink::WebPushPermissionStatusDenied;
457 463
458 // Because the Push API is tied to Service Workers, many usages of the API 464 // Because the Push API is tied to Service Workers, many usages of the API
459 // won't have an embedding origin at all. Only consider the requesting 465 // won't have an embedding origin at all. Only consider the requesting
460 // |origin| when checking whether permission to use the API has been granted. 466 // |origin| when checking whether permission to use the API has been granted.
461 return ToPushPermission(profile_->GetPermissionManager()->GetPermissionStatus( 467 return ToPushPermission(profile_->GetPermissionManager()->GetPermissionStatus(
462 content::PermissionType::PUSH_MESSAGING, origin, origin)); 468 content::PermissionType::PUSH_MESSAGING, origin, origin));
463 } 469 }
464 470
465 bool PushMessagingServiceImpl::SupportNonVisibleMessages() { 471 bool PushMessagingServiceImpl::SupportNonVisibleMessages() {
466 return false; 472 return false;
467 } 473 }
468 474
475 void PushMessagingServiceImpl::DoSubscribe(
476 const PushMessagingAppIdentifier& app_identifier,
477 const content::PushSubscriptionOptions& options,
478 const content::PushMessagingService::RegisterCallback& register_callback,
479 blink::mojom::PermissionStatus permission_status) {
480 if (permission_status != blink::mojom::PermissionStatus::GRANTED) {
481 SubscribeEndWithError(register_callback,
482 content::PUSH_REGISTRATION_STATUS_PERMISSION_DENIED);
483 return;
484 }
485
486 IncreasePushSubscriptionCount(1, true /* is_pending */);
487
488 GetInstanceIDDriver()
489 ->GetInstanceID(app_identifier.app_id())
490 ->GetToken(NormalizeSenderInfo(options.sender_info), kGCMScope,
491 std::map<std::string, std::string>() /* options */,
492 base::Bind(&PushMessagingServiceImpl::DidSubscribe,
493 weak_factory_.GetWeakPtr(), app_identifier,
494 options.sender_info, register_callback));
495 }
496
469 void PushMessagingServiceImpl::SubscribeEnd( 497 void PushMessagingServiceImpl::SubscribeEnd(
470 const content::PushMessagingService::RegisterCallback& callback, 498 const content::PushMessagingService::RegisterCallback& callback,
471 const std::string& subscription_id, 499 const std::string& subscription_id,
472 const std::vector<uint8_t>& p256dh, 500 const std::vector<uint8_t>& p256dh,
473 const std::vector<uint8_t>& auth, 501 const std::vector<uint8_t>& auth,
474 content::PushRegistrationStatus status) { 502 content::PushRegistrationStatus status) {
475 callback.Run(subscription_id, p256dh, auth, status); 503 callback.Run(subscription_id, p256dh, auth, status);
476 } 504 }
477 505
478 void PushMessagingServiceImpl::SubscribeEndWithError( 506 void PushMessagingServiceImpl::SubscribeEndWithError(
479 const content::PushMessagingService::RegisterCallback& callback, 507 const content::PushMessagingService::RegisterCallback& callback,
480 content::PushRegistrationStatus status) { 508 content::PushRegistrationStatus status) {
481 SubscribeEnd(callback, std::string() /* subscription_id */, 509 SubscribeEnd(callback, std::string() /* subscription_id */,
482 std::vector<uint8_t>() /* p256dh */, 510 std::vector<uint8_t>() /* p256dh */,
483 std::vector<uint8_t>() /* auth */, status); 511 std::vector<uint8_t>() /* auth */, status);
484 } 512 }
485 513
486 void PushMessagingServiceImpl::DidSubscribe( 514 void PushMessagingServiceImpl::DidSubscribe(
487 const PushMessagingAppIdentifier& app_identifier, 515 const PushMessagingAppIdentifier& app_identifier,
516 const std::string& sender_id,
488 const content::PushMessagingService::RegisterCallback& callback, 517 const content::PushMessagingService::RegisterCallback& callback,
489 const std::string& subscription_id, 518 const std::string& subscription_id,
490 gcm::GCMClient::Result result) { 519 InstanceID::Result result) {
491 DecreasePushSubscriptionCount(1, true /* was_pending */); 520 DecreasePushSubscriptionCount(1, true /* was_pending */);
492 521
493 content::PushRegistrationStatus status = 522 content::PushRegistrationStatus status =
494 content::PUSH_REGISTRATION_STATUS_SERVICE_ERROR; 523 content::PUSH_REGISTRATION_STATUS_SERVICE_ERROR;
495 524
496 switch (result) { 525 switch (result) {
497 case gcm::GCMClient::SUCCESS: 526 case InstanceID::SUCCESS:
498 // Make sure that this subscription has associated encryption keys prior 527 // Make sure that this subscription has associated encryption keys prior
499 // to returning it to the developer - they'll need this information in 528 // to returning it to the developer - they'll need this information in
500 // order to send payloads to the user. 529 // order to send payloads to the user.
501 GetGCMDriver()->GetEncryptionInfo( 530 GetEncryptionInfoForAppId(
502 app_identifier.app_id(), 531 app_identifier.app_id(), sender_id,
503 base::Bind(&PushMessagingServiceImpl::DidSubscribeWithEncryptionInfo, 532 base::Bind(&PushMessagingServiceImpl::DidSubscribeWithEncryptionInfo,
504 weak_factory_.GetWeakPtr(), app_identifier, callback, 533 weak_factory_.GetWeakPtr(), app_identifier, callback,
505 subscription_id)); 534 subscription_id));
506
507 return; 535 return;
508 case gcm::GCMClient::INVALID_PARAMETER: 536 case InstanceID::INVALID_PARAMETER:
509 case gcm::GCMClient::GCM_DISABLED: 537 case InstanceID::DISABLED:
510 case gcm::GCMClient::ASYNC_OPERATION_PENDING: 538 case InstanceID::ASYNC_OPERATION_PENDING:
511 case gcm::GCMClient::SERVER_ERROR: 539 case InstanceID::SERVER_ERROR:
512 case gcm::GCMClient::UNKNOWN_ERROR: 540 case InstanceID::UNKNOWN_ERROR:
541 DLOG(ERROR) << "Push messaging subscription failed; InstanceID::Result = "
542 << result;
513 status = content::PUSH_REGISTRATION_STATUS_SERVICE_ERROR; 543 status = content::PUSH_REGISTRATION_STATUS_SERVICE_ERROR;
514 break; 544 break;
515 case gcm::GCMClient::NETWORK_ERROR: 545 case InstanceID::NETWORK_ERROR:
516 case gcm::GCMClient::TTL_EXCEEDED:
517 status = content::PUSH_REGISTRATION_STATUS_NETWORK_ERROR; 546 status = content::PUSH_REGISTRATION_STATUS_NETWORK_ERROR;
518 break; 547 break;
519 } 548 }
520 549
521 SubscribeEndWithError(callback, status); 550 SubscribeEndWithError(callback, status);
522 } 551 }
523 552
524 void PushMessagingServiceImpl::DidSubscribeWithEncryptionInfo( 553 void PushMessagingServiceImpl::DidSubscribeWithEncryptionInfo(
525 const PushMessagingAppIdentifier& app_identifier, 554 const PushMessagingAppIdentifier& app_identifier,
526 const content::PushMessagingService::RegisterCallback& callback, 555 const content::PushMessagingService::RegisterCallback& callback,
527 const std::string& subscription_id, 556 const std::string& subscription_id,
528 const std::string& p256dh, 557 const std::string& p256dh,
529 const std::string& auth_secret) { 558 const std::string& auth_secret) {
530 if (p256dh.empty()) { 559 if (p256dh.empty()) {
531 SubscribeEndWithError( 560 SubscribeEndWithError(
532 callback, content::PUSH_REGISTRATION_STATUS_PUBLIC_KEY_UNAVAILABLE); 561 callback, content::PUSH_REGISTRATION_STATUS_PUBLIC_KEY_UNAVAILABLE);
533 return; 562 return;
534 } 563 }
535 564
536 app_identifier.PersistToPrefs(profile_); 565 app_identifier.PersistToPrefs(profile_);
537 566
538 IncreasePushSubscriptionCount(1, false /* is_pending */); 567 IncreasePushSubscriptionCount(1, false /* is_pending */);
539 568
540 SubscribeEnd(callback, subscription_id, 569 SubscribeEnd(callback, subscription_id,
541 std::vector<uint8_t>(p256dh.begin(), p256dh.end()), 570 std::vector<uint8_t>(p256dh.begin(), p256dh.end()),
542 std::vector<uint8_t>(auth_secret.begin(), auth_secret.end()), 571 std::vector<uint8_t>(auth_secret.begin(), auth_secret.end()),
543 content::PUSH_REGISTRATION_STATUS_SUCCESS_FROM_PUSH_SERVICE); 572 content::PUSH_REGISTRATION_STATUS_SUCCESS_FROM_PUSH_SERVICE);
544 } 573 }
545 574
546 void PushMessagingServiceImpl::DidRequestPermission(
547 const PushMessagingAppIdentifier& app_identifier,
548 const content::PushSubscriptionOptions& options,
549 const content::PushMessagingService::RegisterCallback& register_callback,
550 blink::mojom::PermissionStatus permission_status) {
551 if (permission_status != blink::mojom::PermissionStatus::GRANTED) {
552 SubscribeEndWithError(register_callback,
553 content::PUSH_REGISTRATION_STATUS_PERMISSION_DENIED);
554 return;
555 }
556
557 IncreasePushSubscriptionCount(1, true /* is_pending */);
558 std::vector<std::string> sender_ids(1,
559 NormalizeSenderInfo(options.sender_info));
560
561 GetGCMDriver()->Register(app_identifier.app_id(), sender_ids,
562 base::Bind(&PushMessagingServiceImpl::DidSubscribe,
563 weak_factory_.GetWeakPtr(),
564 app_identifier, register_callback));
565 }
566
567 // GetEncryptionInfo methods --------------------------------------------------- 575 // GetEncryptionInfo methods ---------------------------------------------------
568 576
569 void PushMessagingServiceImpl::GetEncryptionInfo( 577 void PushMessagingServiceImpl::GetEncryptionInfo(
570 const GURL& origin, 578 const GURL& origin,
571 int64_t service_worker_registration_id, 579 int64_t service_worker_registration_id,
580 const std::string& sender_id,
572 const PushMessagingService::EncryptionInfoCallback& callback) { 581 const PushMessagingService::EncryptionInfoCallback& callback) {
573 PushMessagingAppIdentifier app_identifier = 582 PushMessagingAppIdentifier app_identifier =
574 PushMessagingAppIdentifier::FindByServiceWorker( 583 PushMessagingAppIdentifier::FindByServiceWorker(
575 profile_, origin, service_worker_registration_id); 584 profile_, origin, service_worker_registration_id);
576 585
577 DCHECK(!app_identifier.is_null()); 586 DCHECK(!app_identifier.is_null());
578 587
579 GetGCMDriver()->GetEncryptionInfo( 588 GetEncryptionInfoForAppId(
580 app_identifier.app_id(), 589 app_identifier.app_id(), sender_id,
581 base::Bind(&PushMessagingServiceImpl::DidGetEncryptionInfo, 590 base::Bind(&PushMessagingServiceImpl::DidGetEncryptionInfo,
582 weak_factory_.GetWeakPtr(), callback)); 591 weak_factory_.GetWeakPtr(), callback));
583 } 592 }
584 593
585 void PushMessagingServiceImpl::DidGetEncryptionInfo( 594 void PushMessagingServiceImpl::DidGetEncryptionInfo(
586 const PushMessagingService::EncryptionInfoCallback& callback, 595 const PushMessagingService::EncryptionInfoCallback& callback,
587 const std::string& p256dh, 596 const std::string& p256dh,
588 const std::string& auth_secret) const { 597 const std::string& auth_secret) const {
589 // I/O errors might prevent the GCM Driver from retrieving a key-pair. 598 // I/O errors might prevent the GCM Driver from retrieving a key-pair.
590 const bool success = !p256dh.empty(); 599 const bool success = !p256dh.empty();
591 600
592 callback.Run(success, std::vector<uint8_t>(p256dh.begin(), p256dh.end()), 601 callback.Run(success, std::vector<uint8_t>(p256dh.begin(), p256dh.end()),
593 std::vector<uint8_t>(auth_secret.begin(), auth_secret.end())); 602 std::vector<uint8_t>(auth_secret.begin(), auth_secret.end()));
594 } 603 }
595 604
596 // Unsubscribe methods --------------------------------------------------------- 605 // Unsubscribe methods ---------------------------------------------------------
597 606
598 void PushMessagingServiceImpl::Unsubscribe( 607 void PushMessagingServiceImpl::Unsubscribe(
599 const GURL& requesting_origin, 608 const GURL& requesting_origin,
600 int64_t service_worker_registration_id, 609 int64_t service_worker_registration_id,
601 const std::string& sender_id, 610 const std::string& sender_id,
602 const content::PushMessagingService::UnregisterCallback& callback) { 611 const content::PushMessagingService::UnregisterCallback& callback) {
603 PushMessagingAppIdentifier app_identifier = 612 PushMessagingAppIdentifier app_identifier =
604 PushMessagingAppIdentifier::FindByServiceWorker( 613 PushMessagingAppIdentifier::FindByServiceWorker(
605 profile_, requesting_origin, service_worker_registration_id); 614 profile_, requesting_origin, service_worker_registration_id);
606 if (app_identifier.is_null()) { 615 if (app_identifier.is_null()) {
607 if (!callback.is_null()) { 616 callback.Run(
608 callback.Run( 617 content::PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED);
609 content::PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED);
610 }
611 return; 618 return;
612 } 619 }
613 620
614 Unsubscribe(app_identifier.app_id(), sender_id, callback); 621 Unsubscribe(app_identifier.app_id(), sender_id, callback);
615 } 622 }
616 623
617 void PushMessagingServiceImpl::Unsubscribe( 624 void PushMessagingServiceImpl::Unsubscribe(
618 const std::string& app_id, 625 const std::string& app_id,
619 const std::string& sender_id, 626 const std::string& sender_id,
620 const content::PushMessagingService::UnregisterCallback& callback) { 627 const content::PushMessagingService::UnregisterCallback& callback) {
621 // Delete the mapping for this app_id, to guarantee that no messages get 628 // Delete the mapping for this app_id, to guarantee that no messages get
622 // delivered in future (even if unregistration fails). 629 // delivered in future (even if unregistration fails).
623 // TODO(johnme): Instead of deleting these app ids, store them elsewhere, and 630 // TODO(johnme): Instead of deleting these app ids, store them elsewhere, and
624 // retry unregistration if it fails due to network errors (crbug.com/465399). 631 // retry unregistration if it fails due to network errors (crbug.com/465399).
625 PushMessagingAppIdentifier app_identifier = 632 PushMessagingAppIdentifier app_identifier =
626 PushMessagingAppIdentifier::FindByAppId(profile_, app_id); 633 PushMessagingAppIdentifier::FindByAppId(profile_, app_id);
627 bool was_registered = !app_identifier.is_null(); 634 bool was_subscribed = !app_identifier.is_null();
628 if (was_registered) 635 if (was_subscribed)
629 app_identifier.DeleteFromPrefs(profile_); 636 app_identifier.DeleteFromPrefs(profile_);
630 637
631 const auto& unregister_callback = 638 if (PushMessagingAppIdentifier::UseInstanceID(app_id)) {
632 base::Bind(&PushMessagingServiceImpl::DidUnsubscribe, 639 GetInstanceIDDriver()->GetInstanceID(app_id)->DeleteID(base::Bind(
633 weak_factory_.GetWeakPtr(), was_registered, callback); 640 &PushMessagingServiceImpl::DidDeleteID, weak_factory_.GetWeakPtr(),
641 app_id, was_subscribed, callback));
642 } else {
643 auto unregister_callback =
644 base::Bind(&PushMessagingServiceImpl::DidUnsubscribe,
645 weak_factory_.GetWeakPtr(), was_subscribed, callback);
634 #if defined(OS_ANDROID) 646 #if defined(OS_ANDROID)
635 // On Android the backend is different, and requires the original sender_id. 647 // On Android the backend is different, and requires the original sender_id.
636 // UnsubscribeBecausePermissionRevoked sometimes calls us with an empty one. 648 // UnsubscribeBecausePermissionRevoked sometimes calls us with an empty one.
637 if (sender_id.empty()) { 649 if (sender_id.empty()) {
638 unregister_callback.Run(gcm::GCMClient::INVALID_PARAMETER); 650 unregister_callback.Run(gcm::GCMClient::INVALID_PARAMETER);
639 } else { 651 } else {
640 GetGCMDriver()->UnregisterWithSenderId( 652 GetGCMDriver()->UnregisterWithSenderId(
641 app_id, NormalizeSenderInfo(sender_id), unregister_callback); 653 app_id, NormalizeSenderInfo(sender_id), unregister_callback);
654 }
655 #else
656 GetGCMDriver()->Unregister(app_id, unregister_callback);
657 #endif
642 } 658 }
643 #else
644 GetGCMDriver()->Unregister(app_id, unregister_callback);
645 #endif
646 } 659 }
647 660
648 void PushMessagingServiceImpl::DidUnsubscribe( 661 void PushMessagingServiceImpl::DidDeleteID(
662 const std::string& app_id,
649 bool was_subscribed, 663 bool was_subscribed,
650 const content::PushMessagingService::UnregisterCallback& callback, 664 const content::PushMessagingService::UnregisterCallback& callback,
651 gcm::GCMClient::Result result) { 665 InstanceID::Result result) {
666 // DidUnsubscribeInstanceID must be run asynchronously, since it calls
667 // InstanceIDDriver::RemoveInstanceID which deletes the InstanceID itself.
668 // Calling that immediately would cause a use-after-free in our caller.
669 base::ThreadTaskRunnerHandle::Get()->PostTask(
670 FROM_HERE, base::Bind(&PushMessagingServiceImpl::DidUnsubscribeInstanceID,
671 weak_factory_.GetWeakPtr(), app_id, was_subscribed,
672 callback, result));
673 }
674
675 void PushMessagingServiceImpl::DidUnsubscribeInstanceID(
676 const std::string& app_id,
677 bool was_subscribed,
678 const content::PushMessagingService::UnregisterCallback& callback,
679 InstanceID::Result result) {
680 GetInstanceIDDriver()->RemoveInstanceID(app_id);
681
652 if (was_subscribed) 682 if (was_subscribed)
653 DecreasePushSubscriptionCount(1, false /* was_pending */); 683 DecreasePushSubscriptionCount(1, false /* was_pending */);
654 684
655 // Internal calls pass a null callback. 685 DCHECK(!callback.is_null());
656 if (callback.is_null())
657 return;
658 686
659 if (!was_subscribed) { 687 if (!was_subscribed) {
660 callback.Run( 688 callback.Run(
661 content::PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED); 689 content::PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED);
662 return; 690 return;
663 } 691 }
664 switch (result) { 692 switch (result) {
693 case InstanceID::SUCCESS:
694 callback.Run(content::PUSH_UNREGISTRATION_STATUS_SUCCESS_UNREGISTERED);
695 break;
696 case InstanceID::INVALID_PARAMETER:
697 case InstanceID::DISABLED:
698 case InstanceID::SERVER_ERROR:
699 case InstanceID::UNKNOWN_ERROR:
700 callback.Run(content::PUSH_UNREGISTRATION_STATUS_PENDING_SERVICE_ERROR);
701 break;
702 case InstanceID::ASYNC_OPERATION_PENDING:
703 case InstanceID::NETWORK_ERROR:
704 callback.Run(content::PUSH_UNREGISTRATION_STATUS_PENDING_NETWORK_ERROR);
705 break;
706 }
707 }
708
709 void PushMessagingServiceImpl::DidUnsubscribe(
710 bool was_subscribed,
711 const content::PushMessagingService::UnregisterCallback& callback,
712 gcm::GCMClient::Result gcm_result) {
713 if (was_subscribed)
714 DecreasePushSubscriptionCount(1, false /* was_pending */);
715
716 DCHECK(!callback.is_null());
717
718 if (!was_subscribed) {
719 callback.Run(
720 content::PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED);
721 return;
722 }
723 switch (gcm_result) {
665 case gcm::GCMClient::SUCCESS: 724 case gcm::GCMClient::SUCCESS:
666 callback.Run(content::PUSH_UNREGISTRATION_STATUS_SUCCESS_UNREGISTERED); 725 callback.Run(content::PUSH_UNREGISTRATION_STATUS_SUCCESS_UNREGISTERED);
667 break; 726 break;
668 case gcm::GCMClient::INVALID_PARAMETER: 727 case gcm::GCMClient::INVALID_PARAMETER:
669 case gcm::GCMClient::GCM_DISABLED: 728 case gcm::GCMClient::GCM_DISABLED:
670 case gcm::GCMClient::SERVER_ERROR: 729 case gcm::GCMClient::SERVER_ERROR:
671 case gcm::GCMClient::UNKNOWN_ERROR: 730 case gcm::GCMClient::UNKNOWN_ERROR:
672 callback.Run(content::PUSH_UNREGISTRATION_STATUS_PENDING_SERVICE_ERROR); 731 callback.Run(content::PUSH_UNREGISTRATION_STATUS_PENDING_SERVICE_ERROR);
673 break; 732 break;
674 case gcm::GCMClient::ASYNC_OPERATION_PENDING: 733 case gcm::GCMClient::ASYNC_OPERATION_PENDING:
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 !primary_pattern.Matches(app_identifier.origin())) { 767 !primary_pattern.Matches(app_identifier.origin())) {
709 barrier_closure.Run(); 768 barrier_closure.Run();
710 continue; 769 continue;
711 } 770 }
712 771
713 if (IsPermissionSet(app_identifier.origin())) { 772 if (IsPermissionSet(app_identifier.origin())) {
714 barrier_closure.Run(); 773 barrier_closure.Run();
715 continue; 774 continue;
716 } 775 }
717 776
718 GetSenderId( 777 bool need_sender_id = false;
719 profile_, app_identifier.origin(), 778 #if defined(OS_ANDROID)
720 app_identifier.service_worker_registration_id(), 779 need_sender_id =
721 base::Bind( 780 !PushMessagingAppIdentifier::UseInstanceID(app_identifier.app_id());
722 &PushMessagingServiceImpl::UnsubscribeBecausePermissionRevoked, 781 #endif
723 weak_factory_.GetWeakPtr(), app_identifier, barrier_closure)); 782 if (need_sender_id) {
783 GetSenderId(
784 profile_, app_identifier.origin(),
785 app_identifier.service_worker_registration_id(),
786 base::Bind(
787 &PushMessagingServiceImpl::UnsubscribeBecausePermissionRevoked,
788 weak_factory_.GetWeakPtr(), app_identifier, barrier_closure));
789 } else {
790 UnsubscribeBecausePermissionRevoked(
791 app_identifier, barrier_closure, "" /* sender_id */,
792 true /* success */, true /* not_found */);
793 }
724 } 794 }
725 } 795 }
726 796
727 void PushMessagingServiceImpl::UnsubscribeBecausePermissionRevoked( 797 void PushMessagingServiceImpl::UnsubscribeBecausePermissionRevoked(
728 const PushMessagingAppIdentifier& app_identifier, 798 const PushMessagingAppIdentifier& app_identifier,
729 const base::Closure& closure, 799 const base::Closure& closure,
730 const std::string& sender_id, 800 const std::string& sender_id,
731 bool success, 801 bool success,
732 bool not_found) { 802 bool not_found) {
733 base::Closure barrier_closure = base::BarrierClosure(2, closure); 803 base::Closure barrier_closure = base::BarrierClosure(2, closure);
734 804
735 // Unsubscribe the PushMessagingAppIdentifier with the push service. 805 // Unsubscribe the PushMessagingAppIdentifier with the push service.
736 // It's possible for GetSenderId to have failed and sender_id to be empty, if 806 // It's possible for GetSenderId to have failed and sender_id to be empty, if
737 // cookies (and the SW database) for an origin got cleared before permissions 807 // cookies (and the SW database) for an origin got cleared before permissions
738 // are cleared for the origin. In that case Unsubscribe will just delete the 808 // are cleared for the origin. In that case for legacy GCM registrations on
739 // app identifier to block future messages. 809 // Android, Unsubscribe will just delete the app identifier to block future
810 // messages.
740 // TODO(johnme): Auto-unregister before SW DB is cleared 811 // TODO(johnme): Auto-unregister before SW DB is cleared
741 // (https://crbug.com/402458). 812 // (https://crbug.com/402458).
742 Unsubscribe(app_identifier.app_id(), sender_id, 813 Unsubscribe(app_identifier.app_id(), sender_id,
743 base::Bind(&UnregisterCallbackToClosure, barrier_closure)); 814 base::Bind(&UnregisterCallbackToClosure, barrier_closure));
744 815
745 // Clear the associated service worker push registration id. 816 // Clear the associated service worker push registration id.
746 ClearPushSubscriptionID(profile_, app_identifier.origin(), 817 ClearPushSubscriptionID(profile_, app_identifier.origin(),
747 app_identifier.service_worker_registration_id(), 818 app_identifier.service_worker_registration_id(),
748 barrier_closure); 819 barrier_closure);
749 } 820 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
792 return encoded_sender_info; 863 return encoded_sender_info;
793 } 864 }
794 865
795 // Assumes user_visible always since this is just meant to check 866 // Assumes user_visible always since this is just meant to check
796 // if the permission was previously granted and not revoked. 867 // if the permission was previously granted and not revoked.
797 bool PushMessagingServiceImpl::IsPermissionSet(const GURL& origin) { 868 bool PushMessagingServiceImpl::IsPermissionSet(const GURL& origin) {
798 return GetPermissionStatus(origin, true /* user_visible */) == 869 return GetPermissionStatus(origin, true /* user_visible */) ==
799 blink::WebPushPermissionStatusGranted; 870 blink::WebPushPermissionStatusGranted;
800 } 871 }
801 872
873 void PushMessagingServiceImpl::GetEncryptionInfoForAppId(
874 const std::string& app_id,
875 const std::string& sender_id,
876 gcm::GCMEncryptionProvider::EncryptionInfoCallback callback) {
877 if (PushMessagingAppIdentifier::UseInstanceID(app_id)) {
878 GetInstanceIDDriver()->GetInstanceID(app_id)->GetEncryptionInfo(
879 NormalizeSenderInfo(sender_id), callback);
880 } else {
881 GetGCMDriver()->GetEncryptionInfo(app_id, callback);
882 }
883 }
884
802 gcm::GCMDriver* PushMessagingServiceImpl::GetGCMDriver() const { 885 gcm::GCMDriver* PushMessagingServiceImpl::GetGCMDriver() const {
803 gcm::GCMProfileService* gcm_profile_service = 886 gcm::GCMProfileService* gcm_profile_service =
804 gcm::GCMProfileServiceFactory::GetForProfile(profile_); 887 gcm::GCMProfileServiceFactory::GetForProfile(profile_);
805 CHECK(gcm_profile_service); 888 CHECK(gcm_profile_service);
806 CHECK(gcm_profile_service->driver()); 889 CHECK(gcm_profile_service->driver());
807 return gcm_profile_service->driver(); 890 return gcm_profile_service->driver();
808 } 891 }
892
893 instance_id::InstanceIDDriver* PushMessagingServiceImpl::GetInstanceIDDriver()
894 const {
895 instance_id::InstanceIDProfileService* instance_id_profile_service =
896 instance_id::InstanceIDProfileServiceFactory::GetForProfile(profile_);
897 CHECK(instance_id_profile_service);
898 CHECK(instance_id_profile_service->driver());
899 return instance_id_profile_service->driver();
900 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698