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

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: Fix GN/GYP 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/bind.h" 10 #include "base/bind.h"
11 #include "base/bind_helpers.h" 11 #include "base/bind_helpers.h"
12 #include "base/callback_helpers.h" 12 #include "base/callback_helpers.h"
13 #include "base/command_line.h" 13 #include "base/command_line.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/metrics/field_trial.h" 15 #include "base/metrics/field_trial.h"
16 #include "base/metrics/histogram.h" 16 #include "base/metrics/histogram.h"
17 #include "build/build_config.h" 17 #include "build/build_config.h"
18 #include "chrome/browser/browser_process.h" 18 #include "chrome/browser/browser_process.h"
19 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" 19 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
20 #include "chrome/browser/permissions/permission_manager.h" 20 #include "chrome/browser/permissions/permission_manager.h"
21 #include "chrome/browser/profiles/profile.h" 21 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/browser/push_messaging/push_messaging_app_identifier.h" 22 #include "chrome/browser/push_messaging/push_messaging_app_identifier.h"
23 #include "chrome/browser/push_messaging/push_messaging_constants.h" 23 #include "chrome/browser/push_messaging/push_messaging_constants.h"
24 #include "chrome/browser/push_messaging/push_messaging_service_factory.h" 24 #include "chrome/browser/push_messaging/push_messaging_service_factory.h"
25 #include "chrome/browser/push_messaging/push_messaging_service_observer.h" 25 #include "chrome/browser/push_messaging/push_messaging_service_observer.h"
26 #include "chrome/browser/services/gcm/gcm_profile_service_factory.h" 26 #include "chrome/browser/services/gcm/gcm_profile_service_factory.h"
27 #include "chrome/browser/services/gcm/instance_id/instance_id_profile_service.h"
28 #include "chrome/browser/services/gcm/instance_id/instance_id_profile_service_fa ctory.h"
27 #include "chrome/browser/ui/chrome_pages.h" 29 #include "chrome/browser/ui/chrome_pages.h"
28 #include "chrome/common/chrome_switches.h" 30 #include "chrome/common/chrome_switches.h"
29 #include "chrome/common/features.h" 31 #include "chrome/common/features.h"
30 #include "chrome/common/pref_names.h" 32 #include "chrome/common/pref_names.h"
31 #include "chrome/grit/generated_resources.h" 33 #include "chrome/grit/generated_resources.h"
32 #include "components/content_settings/core/browser/host_content_settings_map.h" 34 #include "components/content_settings/core/browser/host_content_settings_map.h"
33 #include "components/gcm_driver/gcm_driver.h" 35 #include "components/gcm_driver/gcm_driver.h"
34 #include "components/gcm_driver/gcm_profile_service.h" 36 #include "components/gcm_driver/gcm_profile_service.h"
37 #include "components/gcm_driver/instance_id/instance_id.h"
38 #include "components/gcm_driver/instance_id/instance_id_driver.h"
35 #include "components/pref_registry/pref_registry_syncable.h" 39 #include "components/pref_registry/pref_registry_syncable.h"
36 #include "components/prefs/pref_service.h" 40 #include "components/prefs/pref_service.h"
37 #include "components/rappor/rappor_utils.h" 41 #include "components/rappor/rappor_utils.h"
38 #include "content/public/browser/browser_context.h" 42 #include "content/public/browser/browser_context.h"
39 #include "content/public/browser/permission_type.h" 43 #include "content/public/browser/permission_type.h"
40 #include "content/public/browser/render_frame_host.h" 44 #include "content/public/browser/render_frame_host.h"
41 #include "content/public/browser/service_worker_context.h" 45 #include "content/public/browser/service_worker_context.h"
42 #include "content/public/browser/storage_partition.h" 46 #include "content/public/browser/storage_partition.h"
43 #include "content/public/browser/web_contents.h" 47 #include "content/public/browser/web_contents.h"
44 #include "content/public/common/child_process_host.h" 48 #include "content/public/common/child_process_host.h"
45 #include "content/public/common/content_switches.h" 49 #include "content/public/common/content_switches.h"
46 #include "content/public/common/push_messaging_status.h" 50 #include "content/public/common/push_messaging_status.h"
47 #include "content/public/common/push_subscription_options.h" 51 #include "content/public/common/push_subscription_options.h"
48 #include "ui/base/l10n/l10n_util.h" 52 #include "ui/base/l10n/l10n_util.h"
49 53
50 #if BUILDFLAG(ENABLE_BACKGROUND) 54 #if BUILDFLAG(ENABLE_BACKGROUND)
51 #include "chrome/browser/background/background_mode_manager.h" 55 #include "chrome/browser/background/background_mode_manager.h"
52 #endif 56 #endif
53 57
58 using instance_id::InstanceID;
59
54 namespace { 60 namespace {
61 const char kGCMScope[] = "GCM";
62
55 const int kMaxRegistrations = 1000000; 63 const int kMaxRegistrations = 1000000;
56 64
57 // Chrome does not yet support silent push messages, and requires websites to 65 // Chrome does not yet support silent push messages, and requires websites to
58 // indicate that they will only send user-visible messages. 66 // indicate that they will only send user-visible messages.
59 const char kSilentPushUnsupportedMessage[] = 67 const char kSilentPushUnsupportedMessage[] =
60 "Chrome currently only supports the Push API for subscriptions that will " 68 "Chrome currently only supports the Push API for subscriptions that will "
61 "result in user-visible messages. You can indicate this by calling " 69 "result in user-visible messages. You can indicate this by calling "
62 "pushManager.subscribe({userVisibleOnly: true}) instead. See " 70 "pushManager.subscribe({userVisibleOnly: true}) instead. See "
63 "https://goo.gl/yqv4Q4 for more details."; 71 "https://goo.gl/yqv4Q4 for more details.";
64 72
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 #if BUILDFLAG(ENABLE_BACKGROUND) 180 #if BUILDFLAG(ENABLE_BACKGROUND)
173 if (UseBackgroundMode() && g_browser_process->background_mode_manager()) { 181 if (UseBackgroundMode() && g_browser_process->background_mode_manager()) {
174 g_browser_process->background_mode_manager()->UnregisterTrigger(profile_, 182 g_browser_process->background_mode_manager()->UnregisterTrigger(profile_,
175 this); 183 this);
176 } 184 }
177 #endif // BUILDFLAG(ENABLE_BACKGROUND) 185 #endif // BUILDFLAG(ENABLE_BACKGROUND)
178 } 186 }
179 } 187 }
180 188
181 bool PushMessagingServiceImpl::CanHandle(const std::string& app_id) const { 189 bool PushMessagingServiceImpl::CanHandle(const std::string& app_id) const {
182 return !PushMessagingAppIdentifier::FindByAppId(profile_, app_id).is_null(); 190 return app_id.rfind(kPushMessagingAppIdentifierPrefix, 0) == 0;
183 } 191 }
184 192
185 void PushMessagingServiceImpl::ShutdownHandler() { 193 void PushMessagingServiceImpl::ShutdownHandler() {
186 // Shutdown() should come before and it removes us from the list of app 194 // Shutdown() should come before and it removes us from the list of app
187 // handlers of gcm::GCMDriver so this shouldn't ever been called. 195 // handlers of gcm::GCMDriver so this shouldn't ever been called.
188 NOTREACHED(); 196 NOTREACHED();
189 } 197 }
190 198
191 // OnMessage methods ----------------------------------------------------------- 199 // OnMessage methods -----------------------------------------------------------
192 200
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 completion_closure_runner.Release()); 286 completion_closure_runner.Release());
279 } 287 }
280 #endif 288 #endif
281 break; 289 break;
282 case content::PUSH_DELIVERY_STATUS_INVALID_MESSAGE: 290 case content::PUSH_DELIVERY_STATUS_INVALID_MESSAGE:
283 case content::PUSH_DELIVERY_STATUS_SERVICE_WORKER_ERROR: 291 case content::PUSH_DELIVERY_STATUS_SERVICE_WORKER_ERROR:
284 break; 292 break;
285 case content::PUSH_DELIVERY_STATUS_UNKNOWN_APP_ID: 293 case content::PUSH_DELIVERY_STATUS_UNKNOWN_APP_ID:
286 case content::PUSH_DELIVERY_STATUS_PERMISSION_DENIED: 294 case content::PUSH_DELIVERY_STATUS_PERMISSION_DENIED:
287 case content::PUSH_DELIVERY_STATUS_NO_SERVICE_WORKER: 295 case content::PUSH_DELIVERY_STATUS_NO_SERVICE_WORKER:
288 Unsubscribe(app_id, message.sender_id, 296 Unsubscribe(app_id, base::Bind(&UnregisterCallbackToClosure,
289 base::Bind(&UnregisterCallbackToClosure, 297 completion_closure_runner.Release()));
290 completion_closure_runner.Release()));
291 break; 298 break;
292 } 299 }
293 300
294 RecordDeliveryStatus(status); 301 RecordDeliveryStatus(status);
295 } 302 }
296 303
297 void PushMessagingServiceImpl::DidHandleMessage( 304 void PushMessagingServiceImpl::DidHandleMessage(
298 const std::string& app_id, 305 const std::string& app_id,
299 const base::Closure& message_handled_closure) { 306 const base::Closure& message_handled_closure) {
300 auto in_flight_iterator = in_flight_message_deliveries_.find(app_id); 307 auto in_flight_iterator = in_flight_message_deliveries_.find(app_id);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 content::CONSOLE_MESSAGE_LEVEL_ERROR, kSilentPushUnsupportedMessage); 379 content::CONSOLE_MESSAGE_LEVEL_ERROR, kSilentPushUnsupportedMessage);
373 380
374 SubscribeEndWithError(callback, 381 SubscribeEndWithError(callback,
375 content::PUSH_REGISTRATION_STATUS_PERMISSION_DENIED); 382 content::PUSH_REGISTRATION_STATUS_PERMISSION_DENIED);
376 return; 383 return;
377 } 384 }
378 385
379 // Push does not allow permission requests from iframes. 386 // Push does not allow permission requests from iframes.
380 profile_->GetPermissionManager()->RequestPermission( 387 profile_->GetPermissionManager()->RequestPermission(
381 content::PermissionType::PUSH_MESSAGING, web_contents->GetMainFrame(), 388 content::PermissionType::PUSH_MESSAGING, web_contents->GetMainFrame(),
382 requesting_origin, 389 requesting_origin, base::Bind(&PushMessagingServiceImpl::DoSubscribe,
383 base::Bind(&PushMessagingServiceImpl::DidRequestPermission, 390 weak_factory_.GetWeakPtr(), app_identifier,
384 weak_factory_.GetWeakPtr(), app_identifier, options, 391 options, callback));
385 callback));
386 } 392 }
387 393
388 void PushMessagingServiceImpl::SubscribeFromWorker( 394 void PushMessagingServiceImpl::SubscribeFromWorker(
389 const GURL& requesting_origin, 395 const GURL& requesting_origin,
390 int64_t service_worker_registration_id, 396 int64_t service_worker_registration_id,
391 const content::PushSubscriptionOptions& options, 397 const content::PushSubscriptionOptions& options,
392 const content::PushMessagingService::RegisterCallback& register_callback) { 398 const content::PushMessagingService::RegisterCallback& register_callback) {
393 PushMessagingAppIdentifier app_identifier = 399 PushMessagingAppIdentifier app_identifier =
394 PushMessagingAppIdentifier::Generate(requesting_origin, 400 PushMessagingAppIdentifier::Generate(requesting_origin,
395 service_worker_registration_id); 401 service_worker_registration_id);
396 402
397 if (push_subscription_count_ + pending_push_subscription_count_ >= 403 if (push_subscription_count_ + pending_push_subscription_count_ >=
398 kMaxRegistrations) { 404 kMaxRegistrations) {
399 SubscribeEndWithError(register_callback, 405 SubscribeEndWithError(register_callback,
400 content::PUSH_REGISTRATION_STATUS_LIMIT_REACHED); 406 content::PUSH_REGISTRATION_STATUS_LIMIT_REACHED);
401 return; 407 return;
402 } 408 }
403 409
404 blink::WebPushPermissionStatus permission_status = 410 blink::WebPushPermissionStatus permission_status =
405 PushMessagingServiceImpl::GetPermissionStatus(requesting_origin, 411 PushMessagingServiceImpl::GetPermissionStatus(requesting_origin,
406 options.user_visible_only); 412 options.user_visible_only);
407 413
408 if (permission_status != blink::WebPushPermissionStatusGranted) { 414 if (permission_status != blink::WebPushPermissionStatusGranted) {
409 SubscribeEndWithError(register_callback, 415 SubscribeEndWithError(register_callback,
410 content::PUSH_REGISTRATION_STATUS_PERMISSION_DENIED); 416 content::PUSH_REGISTRATION_STATUS_PERMISSION_DENIED);
411 return; 417 return;
412 } 418 }
413 419
414 IncreasePushSubscriptionCount(1, true /* is_pending */); 420 DoSubscribe(app_identifier, options, register_callback,
415 std::vector<std::string> sender_ids(1, options.sender_info); 421 blink::mojom::PermissionStatus::GRANTED);
416 GetGCMDriver()->Register(app_identifier.app_id(), sender_ids,
417 base::Bind(&PushMessagingServiceImpl::DidSubscribe,
418 weak_factory_.GetWeakPtr(),
419 app_identifier, register_callback));
420 } 422 }
421 423
422 blink::WebPushPermissionStatus PushMessagingServiceImpl::GetPermissionStatus( 424 blink::WebPushPermissionStatus PushMessagingServiceImpl::GetPermissionStatus(
423 const GURL& origin, 425 const GURL& origin,
424 bool user_visible) { 426 bool user_visible) {
425 if (!user_visible) 427 if (!user_visible)
426 return blink::WebPushPermissionStatusDenied; 428 return blink::WebPushPermissionStatusDenied;
427 429
428 // Because the Push API is tied to Service Workers, many usages of the API 430 // Because the Push API is tied to Service Workers, many usages of the API
429 // won't have an embedding origin at all. Only consider the requesting 431 // won't have an embedding origin at all. Only consider the requesting
430 // |origin| when checking whether permission to use the API has been granted. 432 // |origin| when checking whether permission to use the API has been granted.
431 return ToPushPermission(profile_->GetPermissionManager()->GetPermissionStatus( 433 return ToPushPermission(profile_->GetPermissionManager()->GetPermissionStatus(
432 content::PermissionType::PUSH_MESSAGING, origin, origin)); 434 content::PermissionType::PUSH_MESSAGING, origin, origin));
433 } 435 }
434 436
435 bool PushMessagingServiceImpl::SupportNonVisibleMessages() { 437 bool PushMessagingServiceImpl::SupportNonVisibleMessages() {
436 return false; 438 return false;
437 } 439 }
438 440
441 void PushMessagingServiceImpl::DoSubscribe(
442 const PushMessagingAppIdentifier& app_identifier,
443 const content::PushSubscriptionOptions& options,
444 const content::PushMessagingService::RegisterCallback& register_callback,
445 blink::mojom::PermissionStatus permission_status) {
446 if (permission_status != blink::mojom::PermissionStatus::GRANTED) {
447 SubscribeEndWithError(register_callback,
448 content::PUSH_REGISTRATION_STATUS_PERMISSION_DENIED);
449 return;
450 }
451
452 IncreasePushSubscriptionCount(1, true /* is_pending */);
453
454 GetInstanceIDDriver()
455 ->GetInstanceID(app_identifier.app_id())
456 ->GetToken(options.sender_info /* authorized_entity */, kGCMScope,
457 std::map<std::string, std::string>() /* options */,
458 base::Bind(&PushMessagingServiceImpl::DidSubscribe,
459 weak_factory_.GetWeakPtr(), app_identifier,
460 register_callback));
461 }
462
439 void PushMessagingServiceImpl::SubscribeEnd( 463 void PushMessagingServiceImpl::SubscribeEnd(
440 const content::PushMessagingService::RegisterCallback& callback, 464 const content::PushMessagingService::RegisterCallback& callback,
441 const std::string& subscription_id, 465 const std::string& subscription_id,
442 const std::vector<uint8_t>& p256dh, 466 const std::vector<uint8_t>& p256dh,
443 const std::vector<uint8_t>& auth, 467 const std::vector<uint8_t>& auth,
444 content::PushRegistrationStatus status) { 468 content::PushRegistrationStatus status) {
445 callback.Run(subscription_id, p256dh, auth, status); 469 callback.Run(subscription_id, p256dh, auth, status);
446 } 470 }
447 471
448 void PushMessagingServiceImpl::SubscribeEndWithError( 472 void PushMessagingServiceImpl::SubscribeEndWithError(
449 const content::PushMessagingService::RegisterCallback& callback, 473 const content::PushMessagingService::RegisterCallback& callback,
450 content::PushRegistrationStatus status) { 474 content::PushRegistrationStatus status) {
451 SubscribeEnd(callback, std::string() /* subscription_id */, 475 SubscribeEnd(callback, std::string() /* subscription_id */,
452 std::vector<uint8_t>() /* p256dh */, 476 std::vector<uint8_t>() /* p256dh */,
453 std::vector<uint8_t>() /* auth */, status); 477 std::vector<uint8_t>() /* auth */, status);
454 } 478 }
455 479
456 void PushMessagingServiceImpl::DidSubscribe( 480 void PushMessagingServiceImpl::DidSubscribe(
457 const PushMessagingAppIdentifier& app_identifier, 481 const PushMessagingAppIdentifier& app_identifier,
458 const content::PushMessagingService::RegisterCallback& callback, 482 const content::PushMessagingService::RegisterCallback& callback,
459 const std::string& subscription_id, 483 const std::string& subscription_id,
460 gcm::GCMClient::Result result) { 484 InstanceID::Result result) {
461 DecreasePushSubscriptionCount(1, true /* was_pending */); 485 DecreasePushSubscriptionCount(1, true /* was_pending */);
462 486
463 content::PushRegistrationStatus status = 487 content::PushRegistrationStatus status =
464 content::PUSH_REGISTRATION_STATUS_SERVICE_ERROR; 488 content::PUSH_REGISTRATION_STATUS_SERVICE_ERROR;
465 489
466 switch (result) { 490 switch (result) {
467 case gcm::GCMClient::SUCCESS: 491 case InstanceID::SUCCESS:
468 // Make sure that this subscription has associated encryption keys prior 492 // Make sure that this subscription has associated encryption keys prior
469 // to returning it to the developer - they'll need this information in 493 // to returning it to the developer - they'll need this information in
470 // order to send payloads to the user. 494 // order to send payloads to the user.
471 GetGCMDriver()->GetEncryptionInfo( 495 GetGCMDriver()->GetEncryptionInfo(
472 app_identifier.app_id(), 496 app_identifier.app_id(),
473 base::Bind(&PushMessagingServiceImpl::DidSubscribeWithEncryptionInfo, 497 base::Bind(&PushMessagingServiceImpl::DidSubscribeWithEncryptionInfo,
474 weak_factory_.GetWeakPtr(), app_identifier, callback, 498 weak_factory_.GetWeakPtr(), app_identifier, callback,
475 subscription_id)); 499 subscription_id));
476 500
477 return; 501 return;
478 case gcm::GCMClient::INVALID_PARAMETER: 502 case InstanceID::INVALID_PARAMETER:
479 case gcm::GCMClient::GCM_DISABLED: 503 case InstanceID::DISABLED:
480 case gcm::GCMClient::ASYNC_OPERATION_PENDING: 504 case InstanceID::ASYNC_OPERATION_PENDING:
481 case gcm::GCMClient::SERVER_ERROR: 505 case InstanceID::SERVER_ERROR:
482 case gcm::GCMClient::UNKNOWN_ERROR: 506 case InstanceID::UNKNOWN_ERROR:
483 status = content::PUSH_REGISTRATION_STATUS_SERVICE_ERROR; 507 status = content::PUSH_REGISTRATION_STATUS_SERVICE_ERROR;
484 break; 508 break;
485 case gcm::GCMClient::NETWORK_ERROR: 509 case InstanceID::NETWORK_ERROR:
486 case gcm::GCMClient::TTL_EXCEEDED:
487 status = content::PUSH_REGISTRATION_STATUS_NETWORK_ERROR; 510 status = content::PUSH_REGISTRATION_STATUS_NETWORK_ERROR;
488 break; 511 break;
489 } 512 }
490 513
491 SubscribeEndWithError(callback, status); 514 SubscribeEndWithError(callback, status);
492 } 515 }
493 516
494 void PushMessagingServiceImpl::DidSubscribeWithEncryptionInfo( 517 void PushMessagingServiceImpl::DidSubscribeWithEncryptionInfo(
495 const PushMessagingAppIdentifier& app_identifier, 518 const PushMessagingAppIdentifier& app_identifier,
496 const content::PushMessagingService::RegisterCallback& callback, 519 const content::PushMessagingService::RegisterCallback& callback,
497 const std::string& subscription_id, 520 const std::string& subscription_id,
498 const std::string& p256dh, 521 const std::string& p256dh,
499 const std::string& auth_secret) { 522 const std::string& auth_secret) {
500 if (!p256dh.size()) { 523 if (!p256dh.size()) {
501 SubscribeEndWithError( 524 SubscribeEndWithError(
502 callback, content::PUSH_REGISTRATION_STATUS_PUBLIC_KEY_UNAVAILABLE); 525 callback, content::PUSH_REGISTRATION_STATUS_PUBLIC_KEY_UNAVAILABLE);
503 return; 526 return;
504 } 527 }
505 528
506 app_identifier.PersistToPrefs(profile_); 529 app_identifier.PersistToPrefs(profile_);
507 530
508 IncreasePushSubscriptionCount(1, false /* is_pending */); 531 IncreasePushSubscriptionCount(1, false /* is_pending */);
509 532
510 SubscribeEnd(callback, subscription_id, 533 SubscribeEnd(callback, subscription_id,
511 std::vector<uint8_t>(p256dh.begin(), p256dh.end()), 534 std::vector<uint8_t>(p256dh.begin(), p256dh.end()),
512 std::vector<uint8_t>(auth_secret.begin(), auth_secret.end()), 535 std::vector<uint8_t>(auth_secret.begin(), auth_secret.end()),
513 content::PUSH_REGISTRATION_STATUS_SUCCESS_FROM_PUSH_SERVICE); 536 content::PUSH_REGISTRATION_STATUS_SUCCESS_FROM_PUSH_SERVICE);
514 } 537 }
515 538
516 void PushMessagingServiceImpl::DidRequestPermission(
517 const PushMessagingAppIdentifier& app_identifier,
518 const content::PushSubscriptionOptions& options,
519 const content::PushMessagingService::RegisterCallback& register_callback,
520 blink::mojom::PermissionStatus permission_status) {
521 if (permission_status != blink::mojom::PermissionStatus::GRANTED) {
522 SubscribeEndWithError(register_callback,
523 content::PUSH_REGISTRATION_STATUS_PERMISSION_DENIED);
524 return;
525 }
526
527 IncreasePushSubscriptionCount(1, true /* is_pending */);
528 std::vector<std::string> sender_ids(1, options.sender_info);
529 GetGCMDriver()->Register(app_identifier.app_id(), sender_ids,
530 base::Bind(&PushMessagingServiceImpl::DidSubscribe,
531 weak_factory_.GetWeakPtr(),
532 app_identifier, register_callback));
533 }
534
535 // GetEncryptionInfo methods --------------------------------------------------- 539 // GetEncryptionInfo methods ---------------------------------------------------
536 540
537 void PushMessagingServiceImpl::GetEncryptionInfo( 541 void PushMessagingServiceImpl::GetEncryptionInfo(
538 const GURL& origin, 542 const GURL& origin,
539 int64_t service_worker_registration_id, 543 int64_t service_worker_registration_id,
540 const PushMessagingService::EncryptionInfoCallback& callback) { 544 const PushMessagingService::EncryptionInfoCallback& callback) {
541 PushMessagingAppIdentifier app_identifier = 545 PushMessagingAppIdentifier app_identifier =
542 PushMessagingAppIdentifier::FindByServiceWorker( 546 PushMessagingAppIdentifier::FindByServiceWorker(
543 profile_, origin, service_worker_registration_id); 547 profile_, origin, service_worker_registration_id);
544 548
(...skipping 14 matching lines...) Expand all
559 563
560 callback.Run(success, std::vector<uint8_t>(p256dh.begin(), p256dh.end()), 564 callback.Run(success, std::vector<uint8_t>(p256dh.begin(), p256dh.end()),
561 std::vector<uint8_t>(auth_secret.begin(), auth_secret.end())); 565 std::vector<uint8_t>(auth_secret.begin(), auth_secret.end()));
562 } 566 }
563 567
564 // Unsubscribe methods --------------------------------------------------------- 568 // Unsubscribe methods ---------------------------------------------------------
565 569
566 void PushMessagingServiceImpl::Unsubscribe( 570 void PushMessagingServiceImpl::Unsubscribe(
567 const GURL& requesting_origin, 571 const GURL& requesting_origin,
568 int64_t service_worker_registration_id, 572 int64_t service_worker_registration_id,
569 const std::string& sender_id,
570 const content::PushMessagingService::UnregisterCallback& callback) { 573 const content::PushMessagingService::UnregisterCallback& callback) {
571 PushMessagingAppIdentifier app_identifier = 574 PushMessagingAppIdentifier app_identifier =
572 PushMessagingAppIdentifier::FindByServiceWorker( 575 PushMessagingAppIdentifier::FindByServiceWorker(
573 profile_, requesting_origin, service_worker_registration_id); 576 profile_, requesting_origin, service_worker_registration_id);
574 if (app_identifier.is_null()) { 577 if (app_identifier.is_null()) {
575 if (!callback.is_null()) { 578 if (!callback.is_null()) {
576 callback.Run( 579 callback.Run(
577 content::PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED); 580 content::PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED);
578 } 581 }
579 return; 582 return;
580 } 583 }
581 584
582 Unsubscribe(app_identifier.app_id(), sender_id, callback); 585 Unsubscribe(app_identifier.app_id(), callback);
583 } 586 }
584 587
585 void PushMessagingServiceImpl::Unsubscribe( 588 void PushMessagingServiceImpl::Unsubscribe(
586 const std::string& app_id, 589 const std::string& app_id,
587 const std::string& sender_id,
588 const content::PushMessagingService::UnregisterCallback& callback) { 590 const content::PushMessagingService::UnregisterCallback& callback) {
589 // Delete the mapping for this app_id, to guarantee that no messages get 591 // Delete the mapping for this app_id, to guarantee that no messages get
590 // delivered in future (even if unregistration fails). 592 // delivered in future (even if unregistration fails).
591 // TODO(johnme): Instead of deleting these app ids, store them elsewhere, and 593 // TODO(johnme): Instead of deleting these app ids, store them elsewhere, and
592 // retry unregistration if it fails due to network errors (crbug.com/465399). 594 // retry unregistration if it fails due to network errors (crbug.com/465399).
593 PushMessagingAppIdentifier app_identifier = 595 PushMessagingAppIdentifier app_identifier =
594 PushMessagingAppIdentifier::FindByAppId(profile_, app_id); 596 PushMessagingAppIdentifier::FindByAppId(profile_, app_id);
595 bool was_registered = !app_identifier.is_null(); 597 bool was_registered = !app_identifier.is_null();
596 if (was_registered) 598 if (was_registered)
597 app_identifier.DeleteFromPrefs(profile_); 599 app_identifier.DeleteFromPrefs(profile_);
598 600
599 const auto& unregister_callback = 601 GetInstanceIDDriver()->GetInstanceID(app_id)->DeleteID(
600 base::Bind(&PushMessagingServiceImpl::DidUnsubscribe, 602 base::Bind(&PushMessagingServiceImpl::DidUnsubscribe,
601 weak_factory_.GetWeakPtr(), was_registered, callback); 603 weak_factory_.GetWeakPtr(), app_id, was_registered, callback));
602 #if defined(OS_ANDROID)
603 // On Android the backend is different, and requires the original sender_id.
604 // UnsubscribeBecausePermissionRevoked sometimes calls us with an empty one.
605 if (sender_id.empty())
606 unregister_callback.Run(gcm::GCMClient::INVALID_PARAMETER);
607 else
608 GetGCMDriver()->UnregisterWithSenderId(app_id, sender_id,
609 unregister_callback);
610 #else
611 GetGCMDriver()->Unregister(app_id, unregister_callback);
612 #endif
613 } 604 }
614 605
615 void PushMessagingServiceImpl::DidUnsubscribe( 606 void PushMessagingServiceImpl::DidUnsubscribe(
607 const std::string& app_id,
616 bool was_subscribed, 608 bool was_subscribed,
617 const content::PushMessagingService::UnregisterCallback& callback, 609 const content::PushMessagingService::UnregisterCallback& callback,
618 gcm::GCMClient::Result result) { 610 InstanceID::Result result) {
611 GetInstanceIDDriver()->RemoveInstanceID(app_id);
612
619 if (was_subscribed) 613 if (was_subscribed)
620 DecreasePushSubscriptionCount(1, false /* was_pending */); 614 DecreasePushSubscriptionCount(1, false /* was_pending */);
621 615
622 // Internal calls pass a null callback. 616 // Internal calls pass a null callback.
623 if (callback.is_null()) 617 if (callback.is_null())
624 return; 618 return;
625 619
626 if (!was_subscribed) { 620 if (!was_subscribed) {
627 callback.Run( 621 callback.Run(
628 content::PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED); 622 content::PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED);
629 return; 623 return;
630 } 624 }
631 switch (result) { 625 switch (result) {
632 case gcm::GCMClient::SUCCESS: 626 case InstanceID::SUCCESS:
633 callback.Run(content::PUSH_UNREGISTRATION_STATUS_SUCCESS_UNREGISTERED); 627 callback.Run(content::PUSH_UNREGISTRATION_STATUS_SUCCESS_UNREGISTERED);
634 break; 628 break;
635 case gcm::GCMClient::INVALID_PARAMETER: 629 case InstanceID::INVALID_PARAMETER:
636 case gcm::GCMClient::GCM_DISABLED: 630 case InstanceID::DISABLED:
637 case gcm::GCMClient::SERVER_ERROR: 631 case InstanceID::SERVER_ERROR:
638 case gcm::GCMClient::UNKNOWN_ERROR: 632 case InstanceID::UNKNOWN_ERROR:
639 callback.Run(content::PUSH_UNREGISTRATION_STATUS_PENDING_SERVICE_ERROR); 633 callback.Run(content::PUSH_UNREGISTRATION_STATUS_PENDING_SERVICE_ERROR);
640 break; 634 break;
641 case gcm::GCMClient::ASYNC_OPERATION_PENDING: 635 case InstanceID::ASYNC_OPERATION_PENDING:
642 case gcm::GCMClient::NETWORK_ERROR: 636 case InstanceID::NETWORK_ERROR:
643 case gcm::GCMClient::TTL_EXCEEDED:
644 callback.Run(content::PUSH_UNREGISTRATION_STATUS_PENDING_NETWORK_ERROR); 637 callback.Run(content::PUSH_UNREGISTRATION_STATUS_PENDING_NETWORK_ERROR);
645 break; 638 break;
646 } 639 }
647 } 640 }
648 641
649 // OnContentSettingChanged methods --------------------------------------------- 642 // OnContentSettingChanged methods ---------------------------------------------
650 643
651 void PushMessagingServiceImpl::OnContentSettingChanged( 644 void PushMessagingServiceImpl::OnContentSettingChanged(
652 const ContentSettingsPattern& primary_pattern, 645 const ContentSettingsPattern& primary_pattern,
653 const ContentSettingsPattern& secondary_pattern, 646 const ContentSettingsPattern& secondary_pattern,
(...skipping 23 matching lines...) Expand all
677 !primary_pattern.Matches(app_identifier.origin())) { 670 !primary_pattern.Matches(app_identifier.origin())) {
678 barrier_closure.Run(); 671 barrier_closure.Run();
679 continue; 672 continue;
680 } 673 }
681 674
682 if (IsPermissionSet(app_identifier.origin())) { 675 if (IsPermissionSet(app_identifier.origin())) {
683 barrier_closure.Run(); 676 barrier_closure.Run();
684 continue; 677 continue;
685 } 678 }
686 679
687 GetSenderId( 680 UnsubscribeBecausePermissionRevoked(app_identifier, barrier_closure);
688 profile_, app_identifier.origin(),
689 app_identifier.service_worker_registration_id(),
690 base::Bind(
691 &PushMessagingServiceImpl::UnsubscribeBecausePermissionRevoked,
692 weak_factory_.GetWeakPtr(), app_identifier, barrier_closure));
693 } 681 }
694 } 682 }
695 683
696 void PushMessagingServiceImpl::UnsubscribeBecausePermissionRevoked( 684 void PushMessagingServiceImpl::UnsubscribeBecausePermissionRevoked(
697 const PushMessagingAppIdentifier& app_identifier, 685 const PushMessagingAppIdentifier& app_identifier,
698 const base::Closure& closure, 686 const base::Closure& closure) {
699 const std::string& sender_id,
700 bool success,
701 bool not_found) {
702 base::Closure barrier_closure = base::BarrierClosure(2, closure); 687 base::Closure barrier_closure = base::BarrierClosure(2, closure);
703 688
704 // Unsubscribe the PushMessagingAppIdentifier with the push service. 689 Unsubscribe(app_identifier.app_id(),
705 // It's possible for GetSenderId to have failed and sender_id to be empty, if
706 // cookies (and the SW database) for an origin got cleared before permissions
707 // are cleared for the origin. In that case Unsubscribe will just delete the
708 // app identifier to block future messages.
709 // TODO(johnme): Auto-unregister before SW DB is cleared
710 // (https://crbug.com/402458).
711 Unsubscribe(app_identifier.app_id(), sender_id,
712 base::Bind(&UnregisterCallbackToClosure, barrier_closure)); 690 base::Bind(&UnregisterCallbackToClosure, barrier_closure));
713 691
714 // Clear the associated service worker push registration id. 692 // Clear the associated service worker push registration id.
715 ClearPushSubscriptionID(profile_, app_identifier.origin(), 693 ClearPushSubscriptionID(profile_, app_identifier.origin(),
716 app_identifier.service_worker_registration_id(), 694 app_identifier.service_worker_registration_id(),
717 barrier_closure); 695 barrier_closure);
718 } 696 }
719 697
720 void PushMessagingServiceImpl::SetContentSettingChangedCallbackForTesting( 698 void PushMessagingServiceImpl::SetContentSettingChangedCallbackForTesting(
721 const base::Closure& callback) { 699 const base::Closure& callback) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 blink::WebPushPermissionStatusGranted; 732 blink::WebPushPermissionStatusGranted;
755 } 733 }
756 734
757 gcm::GCMDriver* PushMessagingServiceImpl::GetGCMDriver() const { 735 gcm::GCMDriver* PushMessagingServiceImpl::GetGCMDriver() const {
758 gcm::GCMProfileService* gcm_profile_service = 736 gcm::GCMProfileService* gcm_profile_service =
759 gcm::GCMProfileServiceFactory::GetForProfile(profile_); 737 gcm::GCMProfileServiceFactory::GetForProfile(profile_);
760 CHECK(gcm_profile_service); 738 CHECK(gcm_profile_service);
761 CHECK(gcm_profile_service->driver()); 739 CHECK(gcm_profile_service->driver());
762 return gcm_profile_service->driver(); 740 return gcm_profile_service->driver();
763 } 741 }
742
743 instance_id::InstanceIDDriver* PushMessagingServiceImpl::GetInstanceIDDriver()
744 const {
745 instance_id::InstanceIDProfileService* instance_id_profile_service =
746 instance_id::InstanceIDProfileServiceFactory::GetForProfile(profile_);
747 CHECK(instance_id_profile_service);
748 CHECK(instance_id_profile_service->driver());
749 return instance_id_profile_service->driver();
750 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698