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

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

Powered by Google App Engine
This is Rietveld 408576698