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

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: Address review comments, and rewrite following rebase (e.g. no longer depends on NestedMessagePumpA… Created 4 years, 8 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 #endif 57 #endif
54 58
59 using instance_id::InstanceID;
60
55 namespace { 61 namespace {
62 const char kGCMScope[] = "GCM";
Peter Beverloo 2016/04/21 13:26:19 micro nit: blank line after namespace definition.
johnme 2016/05/25 14:11:51 Done.
63
56 const int kMaxRegistrations = 1000000; 64 const int kMaxRegistrations = 1000000;
57 65
58 // Chrome does not yet support silent push messages, and requires websites to 66 // Chrome does not yet support silent push messages, and requires websites to
59 // indicate that they will only send user-visible messages. 67 // indicate that they will only send user-visible messages.
60 const char kSilentPushUnsupportedMessage[] = 68 const char kSilentPushUnsupportedMessage[] =
61 "Chrome currently only supports the Push API for subscriptions that will " 69 "Chrome currently only supports the Push API for subscriptions that will "
62 "result in user-visible messages. You can indicate this by calling " 70 "result in user-visible messages. You can indicate this by calling "
63 "pushManager.subscribe({userVisibleOnly: true}) instead. See " 71 "pushManager.subscribe({userVisibleOnly: true}) instead. See "
64 "https://goo.gl/yqv4Q4 for more details."; 72 "https://goo.gl/yqv4Q4 for more details.";
65 73
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 #if BUILDFLAG(ENABLE_BACKGROUND) 181 #if BUILDFLAG(ENABLE_BACKGROUND)
174 if (UseBackgroundMode() && g_browser_process->background_mode_manager()) { 182 if (UseBackgroundMode() && g_browser_process->background_mode_manager()) {
175 g_browser_process->background_mode_manager()->UnregisterTrigger(profile_, 183 g_browser_process->background_mode_manager()->UnregisterTrigger(profile_,
176 this); 184 this);
177 } 185 }
178 #endif // BUILDFLAG(ENABLE_BACKGROUND) 186 #endif // BUILDFLAG(ENABLE_BACKGROUND)
179 } 187 }
180 } 188 }
181 189
182 bool PushMessagingServiceImpl::CanHandle(const std::string& app_id) const { 190 bool PushMessagingServiceImpl::CanHandle(const std::string& app_id) const {
183 return !PushMessagingAppIdentifier::FindByAppId(profile_, app_id).is_null(); 191 return app_id.rfind(kPushMessagingAppIdentifierPrefix, 0) == 0;
184 } 192 }
185 193
186 void PushMessagingServiceImpl::ShutdownHandler() { 194 void PushMessagingServiceImpl::ShutdownHandler() {
187 // Shutdown() should come before and it removes us from the list of app 195 // Shutdown() should come before and it removes us from the list of app
188 // handlers of gcm::GCMDriver so this shouldn't ever been called. 196 // handlers of gcm::GCMDriver so this shouldn't ever been called.
189 NOTREACHED(); 197 NOTREACHED();
190 } 198 }
191 199
192 // OnMessage methods ----------------------------------------------------------- 200 // OnMessage methods -----------------------------------------------------------
193 201
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 completion_closure_runner.Release()); 287 completion_closure_runner.Release());
280 } 288 }
281 #endif 289 #endif
282 break; 290 break;
283 case content::PUSH_DELIVERY_STATUS_INVALID_MESSAGE: 291 case content::PUSH_DELIVERY_STATUS_INVALID_MESSAGE:
284 case content::PUSH_DELIVERY_STATUS_SERVICE_WORKER_ERROR: 292 case content::PUSH_DELIVERY_STATUS_SERVICE_WORKER_ERROR:
285 break; 293 break;
286 case content::PUSH_DELIVERY_STATUS_UNKNOWN_APP_ID: 294 case content::PUSH_DELIVERY_STATUS_UNKNOWN_APP_ID:
287 case content::PUSH_DELIVERY_STATUS_PERMISSION_DENIED: 295 case content::PUSH_DELIVERY_STATUS_PERMISSION_DENIED:
288 case content::PUSH_DELIVERY_STATUS_NO_SERVICE_WORKER: 296 case content::PUSH_DELIVERY_STATUS_NO_SERVICE_WORKER:
289 Unsubscribe(app_id, message.sender_id, 297 Unsubscribe(app_id, base::Bind(&UnregisterCallbackToClosure,
290 base::Bind(&UnregisterCallbackToClosure, 298 completion_closure_runner.Release()));
291 completion_closure_runner.Release()));
292 break; 299 break;
293 } 300 }
294 301
295 RecordDeliveryStatus(status); 302 RecordDeliveryStatus(status);
296 } 303 }
297 304
298 void PushMessagingServiceImpl::DidHandleMessage( 305 void PushMessagingServiceImpl::DidHandleMessage(
299 const std::string& app_id, 306 const std::string& app_id,
300 const base::Closure& message_handled_closure) { 307 const base::Closure& message_handled_closure) {
301 auto in_flight_iterator = in_flight_message_deliveries_.find(app_id); 308 auto in_flight_iterator = in_flight_message_deliveries_.find(app_id);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 content::CONSOLE_MESSAGE_LEVEL_ERROR, kSilentPushUnsupportedMessage); 380 content::CONSOLE_MESSAGE_LEVEL_ERROR, kSilentPushUnsupportedMessage);
374 381
375 SubscribeEndWithError(callback, 382 SubscribeEndWithError(callback,
376 content::PUSH_REGISTRATION_STATUS_PERMISSION_DENIED); 383 content::PUSH_REGISTRATION_STATUS_PERMISSION_DENIED);
377 return; 384 return;
378 } 385 }
379 386
380 // Push does not allow permission requests from iframes. 387 // Push does not allow permission requests from iframes.
381 profile_->GetPermissionManager()->RequestPermission( 388 profile_->GetPermissionManager()->RequestPermission(
382 content::PermissionType::PUSH_MESSAGING, web_contents->GetMainFrame(), 389 content::PermissionType::PUSH_MESSAGING, web_contents->GetMainFrame(),
383 requesting_origin, 390 requesting_origin, base::Bind(&PushMessagingServiceImpl::DoSubscribe,
384 base::Bind(&PushMessagingServiceImpl::DidRequestPermission, 391 weak_factory_.GetWeakPtr(), app_identifier,
385 weak_factory_.GetWeakPtr(), app_identifier, options, 392 options, callback));
386 callback));
387 } 393 }
388 394
389 void PushMessagingServiceImpl::SubscribeFromWorker( 395 void PushMessagingServiceImpl::SubscribeFromWorker(
390 const GURL& requesting_origin, 396 const GURL& requesting_origin,
391 int64_t service_worker_registration_id, 397 int64_t service_worker_registration_id,
392 const content::PushSubscriptionOptions& options, 398 const content::PushSubscriptionOptions& options,
393 const content::PushMessagingService::RegisterCallback& register_callback) { 399 const content::PushMessagingService::RegisterCallback& register_callback) {
394 PushMessagingAppIdentifier app_identifier = 400 PushMessagingAppIdentifier app_identifier =
395 PushMessagingAppIdentifier::Generate(requesting_origin, 401 PushMessagingAppIdentifier::Generate(requesting_origin,
396 service_worker_registration_id); 402 service_worker_registration_id);
397 403
398 if (push_subscription_count_ + pending_push_subscription_count_ >= 404 if (push_subscription_count_ + pending_push_subscription_count_ >=
399 kMaxRegistrations) { 405 kMaxRegistrations) {
400 SubscribeEndWithError(register_callback, 406 SubscribeEndWithError(register_callback,
401 content::PUSH_REGISTRATION_STATUS_LIMIT_REACHED); 407 content::PUSH_REGISTRATION_STATUS_LIMIT_REACHED);
402 return; 408 return;
403 } 409 }
404 410
405 blink::WebPushPermissionStatus permission_status = 411 blink::WebPushPermissionStatus permission_status =
406 PushMessagingServiceImpl::GetPermissionStatus(requesting_origin, 412 PushMessagingServiceImpl::GetPermissionStatus(requesting_origin,
Peter Beverloo 2016/04/21 13:26:19 What's up with this call? I.e. why isn't it this->
johnme 2016/05/25 14:11:51 Weird. Removed the PushMessagingServiceImpl::.
407 options.user_visible_only); 413 options.user_visible_only);
408 414
409 if (permission_status != blink::WebPushPermissionStatusGranted) { 415 if (permission_status != blink::WebPushPermissionStatusGranted) {
410 SubscribeEndWithError(register_callback, 416 SubscribeEndWithError(register_callback,
411 content::PUSH_REGISTRATION_STATUS_PERMISSION_DENIED); 417 content::PUSH_REGISTRATION_STATUS_PERMISSION_DENIED);
412 return; 418 return;
413 } 419 }
414 420
415 IncreasePushSubscriptionCount(1, true /* is_pending */); 421 DoSubscribe(app_identifier, options, register_callback,
416 std::vector<std::string> sender_ids(1, 422 blink::mojom::PermissionStatus::GRANTED);
417 NormalizeSenderInfo(options.sender_info));
418
419 GetGCMDriver()->Register(app_identifier.app_id(), sender_ids,
420 base::Bind(&PushMessagingServiceImpl::DidSubscribe,
421 weak_factory_.GetWeakPtr(),
422 app_identifier, register_callback));
423 } 423 }
424 424
425 blink::WebPushPermissionStatus PushMessagingServiceImpl::GetPermissionStatus( 425 blink::WebPushPermissionStatus PushMessagingServiceImpl::GetPermissionStatus(
426 const GURL& origin, 426 const GURL& origin,
427 bool user_visible) { 427 bool user_visible) {
428 if (!user_visible) 428 if (!user_visible)
429 return blink::WebPushPermissionStatusDenied; 429 return blink::WebPushPermissionStatusDenied;
430 430
431 // Because the Push API is tied to Service Workers, many usages of the API 431 // Because the Push API is tied to Service Workers, many usages of the API
432 // won't have an embedding origin at all. Only consider the requesting 432 // won't have an embedding origin at all. Only consider the requesting
433 // |origin| when checking whether permission to use the API has been granted. 433 // |origin| when checking whether permission to use the API has been granted.
434 return ToPushPermission(profile_->GetPermissionManager()->GetPermissionStatus( 434 return ToPushPermission(profile_->GetPermissionManager()->GetPermissionStatus(
435 content::PermissionType::PUSH_MESSAGING, origin, origin)); 435 content::PermissionType::PUSH_MESSAGING, origin, origin));
436 } 436 }
437 437
438 bool PushMessagingServiceImpl::SupportNonVisibleMessages() { 438 bool PushMessagingServiceImpl::SupportNonVisibleMessages() {
439 return false; 439 return false;
440 } 440 }
441 441
442 void PushMessagingServiceImpl::DoSubscribe(
443 const PushMessagingAppIdentifier& app_identifier,
444 const content::PushSubscriptionOptions& options,
445 const content::PushMessagingService::RegisterCallback& register_callback,
446 blink::mojom::PermissionStatus permission_status) {
447 if (permission_status != blink::mojom::PermissionStatus::GRANTED) {
448 SubscribeEndWithError(register_callback,
449 content::PUSH_REGISTRATION_STATUS_PERMISSION_DENIED);
450 return;
451 }
452
453 IncreasePushSubscriptionCount(1, true /* is_pending */);
454
455 GetInstanceIDDriver()
456 ->GetInstanceID(app_identifier.app_id())
457 ->GetToken(
458 NormalizeSenderInfo(options.sender_info) /* authorized_entity */,
459 kGCMScope, std::map<std::string, std::string>() /* options */,
460 base::Bind(&PushMessagingServiceImpl::DidSubscribe,
461 weak_factory_.GetWeakPtr(), app_identifier,
462 register_callback));
463 }
464
442 void PushMessagingServiceImpl::SubscribeEnd( 465 void PushMessagingServiceImpl::SubscribeEnd(
443 const content::PushMessagingService::RegisterCallback& callback, 466 const content::PushMessagingService::RegisterCallback& callback,
444 const std::string& subscription_id, 467 const std::string& subscription_id,
445 const std::vector<uint8_t>& p256dh, 468 const std::vector<uint8_t>& p256dh,
446 const std::vector<uint8_t>& auth, 469 const std::vector<uint8_t>& auth,
447 content::PushRegistrationStatus status) { 470 content::PushRegistrationStatus status) {
448 callback.Run(subscription_id, p256dh, auth, status); 471 callback.Run(subscription_id, p256dh, auth, status);
449 } 472 }
450 473
451 void PushMessagingServiceImpl::SubscribeEndWithError( 474 void PushMessagingServiceImpl::SubscribeEndWithError(
452 const content::PushMessagingService::RegisterCallback& callback, 475 const content::PushMessagingService::RegisterCallback& callback,
453 content::PushRegistrationStatus status) { 476 content::PushRegistrationStatus status) {
454 SubscribeEnd(callback, std::string() /* subscription_id */, 477 SubscribeEnd(callback, std::string() /* subscription_id */,
455 std::vector<uint8_t>() /* p256dh */, 478 std::vector<uint8_t>() /* p256dh */,
456 std::vector<uint8_t>() /* auth */, status); 479 std::vector<uint8_t>() /* auth */, status);
457 } 480 }
458 481
459 void PushMessagingServiceImpl::DidSubscribe( 482 void PushMessagingServiceImpl::DidSubscribe(
460 const PushMessagingAppIdentifier& app_identifier, 483 const PushMessagingAppIdentifier& app_identifier,
461 const content::PushMessagingService::RegisterCallback& callback, 484 const content::PushMessagingService::RegisterCallback& callback,
462 const std::string& subscription_id, 485 const std::string& subscription_id,
463 gcm::GCMClient::Result result) { 486 InstanceID::Result result) {
464 DecreasePushSubscriptionCount(1, true /* was_pending */); 487 DecreasePushSubscriptionCount(1, true /* was_pending */);
465 488
466 content::PushRegistrationStatus status = 489 content::PushRegistrationStatus status =
467 content::PUSH_REGISTRATION_STATUS_SERVICE_ERROR; 490 content::PUSH_REGISTRATION_STATUS_SERVICE_ERROR;
468 491
469 switch (result) { 492 switch (result) {
470 case gcm::GCMClient::SUCCESS: 493 case InstanceID::SUCCESS:
471 // Make sure that this subscription has associated encryption keys prior 494 // Make sure that this subscription has associated encryption keys prior
472 // to returning it to the developer - they'll need this information in 495 // to returning it to the developer - they'll need this information in
473 // order to send payloads to the user. 496 // order to send payloads to the user.
474 GetGCMDriver()->GetEncryptionInfo( 497 GetGCMDriver()->GetEncryptionInfo(
475 app_identifier.app_id(), 498 app_identifier.app_id(),
476 base::Bind(&PushMessagingServiceImpl::DidSubscribeWithEncryptionInfo, 499 base::Bind(&PushMessagingServiceImpl::DidSubscribeWithEncryptionInfo,
477 weak_factory_.GetWeakPtr(), app_identifier, callback, 500 weak_factory_.GetWeakPtr(), app_identifier, callback,
478 subscription_id)); 501 subscription_id));
479 502
480 return; 503 return;
481 case gcm::GCMClient::INVALID_PARAMETER: 504 case InstanceID::INVALID_PARAMETER:
482 case gcm::GCMClient::GCM_DISABLED: 505 case InstanceID::DISABLED:
483 case gcm::GCMClient::ASYNC_OPERATION_PENDING: 506 case InstanceID::ASYNC_OPERATION_PENDING:
484 case gcm::GCMClient::SERVER_ERROR: 507 case InstanceID::SERVER_ERROR:
485 case gcm::GCMClient::UNKNOWN_ERROR: 508 case InstanceID::UNKNOWN_ERROR:
486 status = content::PUSH_REGISTRATION_STATUS_SERVICE_ERROR; 509 status = content::PUSH_REGISTRATION_STATUS_SERVICE_ERROR;
Peter Beverloo 2016/04/21 13:26:18 I'm beginning to think we should consider having D
johnme 2016/05/25 14:11:51 Done (hopefully it won't trigger too often; in the
487 break; 510 break;
488 case gcm::GCMClient::NETWORK_ERROR: 511 case InstanceID::NETWORK_ERROR:
489 case gcm::GCMClient::TTL_EXCEEDED:
490 status = content::PUSH_REGISTRATION_STATUS_NETWORK_ERROR; 512 status = content::PUSH_REGISTRATION_STATUS_NETWORK_ERROR;
491 break; 513 break;
492 } 514 }
493 515
494 SubscribeEndWithError(callback, status); 516 SubscribeEndWithError(callback, status);
495 } 517 }
496 518
497 void PushMessagingServiceImpl::DidSubscribeWithEncryptionInfo( 519 void PushMessagingServiceImpl::DidSubscribeWithEncryptionInfo(
498 const PushMessagingAppIdentifier& app_identifier, 520 const PushMessagingAppIdentifier& app_identifier,
499 const content::PushMessagingService::RegisterCallback& callback, 521 const content::PushMessagingService::RegisterCallback& callback,
500 const std::string& subscription_id, 522 const std::string& subscription_id,
501 const std::string& p256dh, 523 const std::string& p256dh,
502 const std::string& auth_secret) { 524 const std::string& auth_secret) {
503 if (!p256dh.size()) { 525 if (!p256dh.size()) {
504 SubscribeEndWithError( 526 SubscribeEndWithError(
505 callback, content::PUSH_REGISTRATION_STATUS_PUBLIC_KEY_UNAVAILABLE); 527 callback, content::PUSH_REGISTRATION_STATUS_PUBLIC_KEY_UNAVAILABLE);
506 return; 528 return;
507 } 529 }
508 530
509 app_identifier.PersistToPrefs(profile_); 531 app_identifier.PersistToPrefs(profile_);
510 532
511 IncreasePushSubscriptionCount(1, false /* is_pending */); 533 IncreasePushSubscriptionCount(1, false /* is_pending */);
512 534
513 SubscribeEnd(callback, subscription_id, 535 SubscribeEnd(callback, subscription_id,
514 std::vector<uint8_t>(p256dh.begin(), p256dh.end()), 536 std::vector<uint8_t>(p256dh.begin(), p256dh.end()),
515 std::vector<uint8_t>(auth_secret.begin(), auth_secret.end()), 537 std::vector<uint8_t>(auth_secret.begin(), auth_secret.end()),
516 content::PUSH_REGISTRATION_STATUS_SUCCESS_FROM_PUSH_SERVICE); 538 content::PUSH_REGISTRATION_STATUS_SUCCESS_FROM_PUSH_SERVICE);
517 } 539 }
518 540
519 void PushMessagingServiceImpl::DidRequestPermission(
520 const PushMessagingAppIdentifier& app_identifier,
521 const content::PushSubscriptionOptions& options,
522 const content::PushMessagingService::RegisterCallback& register_callback,
523 blink::mojom::PermissionStatus permission_status) {
524 if (permission_status != blink::mojom::PermissionStatus::GRANTED) {
525 SubscribeEndWithError(register_callback,
526 content::PUSH_REGISTRATION_STATUS_PERMISSION_DENIED);
527 return;
528 }
529
530 IncreasePushSubscriptionCount(1, true /* is_pending */);
531 std::vector<std::string> sender_ids(1,
532 NormalizeSenderInfo(options.sender_info));
533
534 GetGCMDriver()->Register(app_identifier.app_id(), sender_ids,
535 base::Bind(&PushMessagingServiceImpl::DidSubscribe,
536 weak_factory_.GetWeakPtr(),
537 app_identifier, register_callback));
538 }
539
540 // GetEncryptionInfo methods --------------------------------------------------- 541 // GetEncryptionInfo methods ---------------------------------------------------
541 542
542 void PushMessagingServiceImpl::GetEncryptionInfo( 543 void PushMessagingServiceImpl::GetEncryptionInfo(
543 const GURL& origin, 544 const GURL& origin,
544 int64_t service_worker_registration_id, 545 int64_t service_worker_registration_id,
545 const PushMessagingService::EncryptionInfoCallback& callback) { 546 const PushMessagingService::EncryptionInfoCallback& callback) {
546 PushMessagingAppIdentifier app_identifier = 547 PushMessagingAppIdentifier app_identifier =
547 PushMessagingAppIdentifier::FindByServiceWorker( 548 PushMessagingAppIdentifier::FindByServiceWorker(
548 profile_, origin, service_worker_registration_id); 549 profile_, origin, service_worker_registration_id);
549 550
(...skipping 14 matching lines...) Expand all
564 565
565 callback.Run(success, std::vector<uint8_t>(p256dh.begin(), p256dh.end()), 566 callback.Run(success, std::vector<uint8_t>(p256dh.begin(), p256dh.end()),
566 std::vector<uint8_t>(auth_secret.begin(), auth_secret.end())); 567 std::vector<uint8_t>(auth_secret.begin(), auth_secret.end()));
567 } 568 }
568 569
569 // Unsubscribe methods --------------------------------------------------------- 570 // Unsubscribe methods ---------------------------------------------------------
570 571
571 void PushMessagingServiceImpl::Unsubscribe( 572 void PushMessagingServiceImpl::Unsubscribe(
572 const GURL& requesting_origin, 573 const GURL& requesting_origin,
573 int64_t service_worker_registration_id, 574 int64_t service_worker_registration_id,
574 const std::string& sender_id,
575 const content::PushMessagingService::UnregisterCallback& callback) { 575 const content::PushMessagingService::UnregisterCallback& callback) {
576 PushMessagingAppIdentifier app_identifier = 576 PushMessagingAppIdentifier app_identifier =
577 PushMessagingAppIdentifier::FindByServiceWorker( 577 PushMessagingAppIdentifier::FindByServiceWorker(
578 profile_, requesting_origin, service_worker_registration_id); 578 profile_, requesting_origin, service_worker_registration_id);
579 if (app_identifier.is_null()) { 579 if (app_identifier.is_null()) {
580 if (!callback.is_null()) { 580 if (!callback.is_null()) {
581 callback.Run( 581 callback.Run(
582 content::PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED); 582 content::PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED);
583 } 583 }
584 return; 584 return;
585 } 585 }
586 586
587 Unsubscribe(app_identifier.app_id(), sender_id, callback); 587 Unsubscribe(app_identifier.app_id(), callback);
588 } 588 }
589 589
590 void PushMessagingServiceImpl::Unsubscribe( 590 void PushMessagingServiceImpl::Unsubscribe(
591 const std::string& app_id, 591 const std::string& app_id,
592 const std::string& sender_id,
593 const content::PushMessagingService::UnregisterCallback& callback) { 592 const content::PushMessagingService::UnregisterCallback& callback) {
594 // Delete the mapping for this app_id, to guarantee that no messages get 593 // Delete the mapping for this app_id, to guarantee that no messages get
595 // delivered in future (even if unregistration fails). 594 // delivered in future (even if unregistration fails).
596 // TODO(johnme): Instead of deleting these app ids, store them elsewhere, and 595 // TODO(johnme): Instead of deleting these app ids, store them elsewhere, and
597 // retry unregistration if it fails due to network errors (crbug.com/465399). 596 // retry unregistration if it fails due to network errors (crbug.com/465399).
598 PushMessagingAppIdentifier app_identifier = 597 PushMessagingAppIdentifier app_identifier =
599 PushMessagingAppIdentifier::FindByAppId(profile_, app_id); 598 PushMessagingAppIdentifier::FindByAppId(profile_, app_id);
600 bool was_registered = !app_identifier.is_null(); 599 bool was_registered = !app_identifier.is_null();
601 if (was_registered) 600 if (was_registered)
602 app_identifier.DeleteFromPrefs(profile_); 601 app_identifier.DeleteFromPrefs(profile_);
603 602
604 const auto& unregister_callback = 603 GetInstanceIDDriver()->GetInstanceID(app_id)->DeleteID(
Peter Beverloo 2016/04/21 13:26:18 Now that we don't call GCMDriver::Unregister(WithS
johnme 2016/05/25 14:11:51 848 lines later... Done (https://codereview.chromi
605 base::Bind(&PushMessagingServiceImpl::DidUnsubscribe, 604 base::Bind(&PushMessagingServiceImpl::DidUnsubscribe,
606 weak_factory_.GetWeakPtr(), was_registered, callback); 605 weak_factory_.GetWeakPtr(), app_id, was_registered, callback));
607 #if defined(OS_ANDROID)
608 // On Android the backend is different, and requires the original sender_id.
609 // UnsubscribeBecausePermissionRevoked sometimes calls us with an empty one.
610 if (sender_id.empty()) {
611 unregister_callback.Run(gcm::GCMClient::INVALID_PARAMETER);
612 } else {
613 GetGCMDriver()->UnregisterWithSenderId(
614 app_id, NormalizeSenderInfo(sender_id), unregister_callback);
615 }
616 #else
617 GetGCMDriver()->Unregister(app_id, unregister_callback);
618 #endif
619 } 606 }
620 607
621 void PushMessagingServiceImpl::DidUnsubscribe( 608 void PushMessagingServiceImpl::DidUnsubscribe(
609 const std::string& app_id,
622 bool was_subscribed, 610 bool was_subscribed,
623 const content::PushMessagingService::UnregisterCallback& callback, 611 const content::PushMessagingService::UnregisterCallback& callback,
624 gcm::GCMClient::Result result) { 612 InstanceID::Result result) {
613 GetInstanceIDDriver()->RemoveInstanceID(app_id);
614
625 if (was_subscribed) 615 if (was_subscribed)
626 DecreasePushSubscriptionCount(1, false /* was_pending */); 616 DecreasePushSubscriptionCount(1, false /* was_pending */);
627 617
628 // Internal calls pass a null callback. 618 // Internal calls pass a null callback.
629 if (callback.is_null()) 619 if (callback.is_null())
Peter Beverloo 2016/04/21 13:26:18 While not related to your CL, this isn't true anym
johnme 2016/05/25 14:11:51 Done.
630 return; 620 return;
631 621
632 if (!was_subscribed) { 622 if (!was_subscribed) {
633 callback.Run( 623 callback.Run(
634 content::PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED); 624 content::PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED);
635 return; 625 return;
636 } 626 }
637 switch (result) { 627 switch (result) {
638 case gcm::GCMClient::SUCCESS: 628 case InstanceID::SUCCESS:
639 callback.Run(content::PUSH_UNREGISTRATION_STATUS_SUCCESS_UNREGISTERED); 629 callback.Run(content::PUSH_UNREGISTRATION_STATUS_SUCCESS_UNREGISTERED);
640 break; 630 break;
641 case gcm::GCMClient::INVALID_PARAMETER: 631 case InstanceID::INVALID_PARAMETER:
642 case gcm::GCMClient::GCM_DISABLED: 632 case InstanceID::DISABLED:
643 case gcm::GCMClient::SERVER_ERROR: 633 case InstanceID::SERVER_ERROR:
644 case gcm::GCMClient::UNKNOWN_ERROR: 634 case InstanceID::UNKNOWN_ERROR:
645 callback.Run(content::PUSH_UNREGISTRATION_STATUS_PENDING_SERVICE_ERROR); 635 callback.Run(content::PUSH_UNREGISTRATION_STATUS_PENDING_SERVICE_ERROR);
646 break; 636 break;
647 case gcm::GCMClient::ASYNC_OPERATION_PENDING: 637 case InstanceID::ASYNC_OPERATION_PENDING:
648 case gcm::GCMClient::NETWORK_ERROR: 638 case InstanceID::NETWORK_ERROR:
649 case gcm::GCMClient::TTL_EXCEEDED:
650 callback.Run(content::PUSH_UNREGISTRATION_STATUS_PENDING_NETWORK_ERROR); 639 callback.Run(content::PUSH_UNREGISTRATION_STATUS_PENDING_NETWORK_ERROR);
651 break; 640 break;
652 } 641 }
653 } 642 }
654 643
655 // OnContentSettingChanged methods --------------------------------------------- 644 // OnContentSettingChanged methods ---------------------------------------------
656 645
657 void PushMessagingServiceImpl::OnContentSettingChanged( 646 void PushMessagingServiceImpl::OnContentSettingChanged(
658 const ContentSettingsPattern& primary_pattern, 647 const ContentSettingsPattern& primary_pattern,
659 const ContentSettingsPattern& secondary_pattern, 648 const ContentSettingsPattern& secondary_pattern,
(...skipping 23 matching lines...) Expand all
683 !primary_pattern.Matches(app_identifier.origin())) { 672 !primary_pattern.Matches(app_identifier.origin())) {
684 barrier_closure.Run(); 673 barrier_closure.Run();
685 continue; 674 continue;
686 } 675 }
687 676
688 if (IsPermissionSet(app_identifier.origin())) { 677 if (IsPermissionSet(app_identifier.origin())) {
689 barrier_closure.Run(); 678 barrier_closure.Run();
690 continue; 679 continue;
691 } 680 }
692 681
693 GetSenderId( 682 UnsubscribeBecausePermissionRevoked(app_identifier, barrier_closure);
Peter Beverloo 2016/04/21 13:26:19 Can we coalesce UnsubscribeBecausePermissionRevoke
johnme 2016/05/25 14:11:51 Not any more - I had to re-add the async GetSender
694 profile_, app_identifier.origin(),
695 app_identifier.service_worker_registration_id(),
696 base::Bind(
697 &PushMessagingServiceImpl::UnsubscribeBecausePermissionRevoked,
698 weak_factory_.GetWeakPtr(), app_identifier, barrier_closure));
699 } 683 }
700 } 684 }
701 685
702 void PushMessagingServiceImpl::UnsubscribeBecausePermissionRevoked( 686 void PushMessagingServiceImpl::UnsubscribeBecausePermissionRevoked(
703 const PushMessagingAppIdentifier& app_identifier, 687 const PushMessagingAppIdentifier& app_identifier,
704 const base::Closure& closure, 688 const base::Closure& closure) {
705 const std::string& sender_id,
706 bool success,
707 bool not_found) {
708 base::Closure barrier_closure = base::BarrierClosure(2, closure); 689 base::Closure barrier_closure = base::BarrierClosure(2, closure);
709 690
710 // Unsubscribe the PushMessagingAppIdentifier with the push service. 691 Unsubscribe(app_identifier.app_id(),
711 // It's possible for GetSenderId to have failed and sender_id to be empty, if
712 // cookies (and the SW database) for an origin got cleared before permissions
713 // are cleared for the origin. In that case Unsubscribe will just delete the
714 // app identifier to block future messages.
715 // TODO(johnme): Auto-unregister before SW DB is cleared
716 // (https://crbug.com/402458).
Peter Beverloo 2016/04/21 13:26:19 Now that we no longer rely on the sender_id I thin
johnme 2016/05/25 14:11:51 Yup - the future is bright! Though unfortunately,
717 Unsubscribe(app_identifier.app_id(), sender_id,
718 base::Bind(&UnregisterCallbackToClosure, barrier_closure)); 692 base::Bind(&UnregisterCallbackToClosure, barrier_closure));
719 693
720 // Clear the associated service worker push registration id. 694 // Clear the associated service worker push registration id.
721 ClearPushSubscriptionID(profile_, app_identifier.origin(), 695 ClearPushSubscriptionID(profile_, app_identifier.origin(),
722 app_identifier.service_worker_registration_id(), 696 app_identifier.service_worker_registration_id(),
723 barrier_closure); 697 barrier_closure);
724 } 698 }
725 699
726 void PushMessagingServiceImpl::SetContentSettingChangedCallbackForTesting( 700 void PushMessagingServiceImpl::SetContentSettingChangedCallbackForTesting(
727 const base::Closure& callback) { 701 const base::Closure& callback) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
774 blink::WebPushPermissionStatusGranted; 748 blink::WebPushPermissionStatusGranted;
775 } 749 }
776 750
777 gcm::GCMDriver* PushMessagingServiceImpl::GetGCMDriver() const { 751 gcm::GCMDriver* PushMessagingServiceImpl::GetGCMDriver() const {
778 gcm::GCMProfileService* gcm_profile_service = 752 gcm::GCMProfileService* gcm_profile_service =
779 gcm::GCMProfileServiceFactory::GetForProfile(profile_); 753 gcm::GCMProfileServiceFactory::GetForProfile(profile_);
780 CHECK(gcm_profile_service); 754 CHECK(gcm_profile_service);
781 CHECK(gcm_profile_service->driver()); 755 CHECK(gcm_profile_service->driver());
782 return gcm_profile_service->driver(); 756 return gcm_profile_service->driver();
783 } 757 }
758
759 instance_id::InstanceIDDriver* PushMessagingServiceImpl::GetInstanceIDDriver()
760 const {
761 instance_id::InstanceIDProfileService* instance_id_profile_service =
762 instance_id::InstanceIDProfileServiceFactory::GetForProfile(profile_);
763 CHECK(instance_id_profile_service);
764 CHECK(instance_id_profile_service->driver());
765 return instance_id_profile_service->driver();
766 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698