OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/push_messaging/push_messaging_service_impl.h" | 5 #include "chrome/browser/push_messaging/push_messaging_service_impl.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/barrier_closure.h" | 9 #include "base/barrier_closure.h" |
10 #include "base/base64url.h" | 10 #include "base/base64url.h" |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 "Chrome currently only supports the Push API for subscriptions that will " | 76 "Chrome currently only supports the Push API for subscriptions that will " |
77 "result in user-visible messages. You can indicate this by calling " | 77 "result in user-visible messages. You can indicate this by calling " |
78 "pushManager.subscribe({userVisibleOnly: true}) instead. See " | 78 "pushManager.subscribe({userVisibleOnly: true}) instead. See " |
79 "https://goo.gl/yqv4Q4 for more details."; | 79 "https://goo.gl/yqv4Q4 for more details."; |
80 | 80 |
81 void RecordDeliveryStatus(content::PushDeliveryStatus status) { | 81 void RecordDeliveryStatus(content::PushDeliveryStatus status) { |
82 UMA_HISTOGRAM_ENUMERATION("PushMessaging.DeliveryStatus", status, | 82 UMA_HISTOGRAM_ENUMERATION("PushMessaging.DeliveryStatus", status, |
83 content::PUSH_DELIVERY_STATUS_LAST + 1); | 83 content::PUSH_DELIVERY_STATUS_LAST + 1); |
84 } | 84 } |
85 | 85 |
| 86 void RecordUnsubscribeReason(content::PushUnregistrationReason reason) { |
| 87 UMA_HISTOGRAM_ENUMERATION("PushMessaging.UnregistrationReason", reason, |
| 88 content::PUSH_UNREGISTRATION_REASON_LAST + 1); |
| 89 } |
| 90 |
86 blink::WebPushPermissionStatus ToPushPermission( | 91 blink::WebPushPermissionStatus ToPushPermission( |
87 blink::mojom::PermissionStatus permission_status) { | 92 blink::mojom::PermissionStatus permission_status) { |
88 switch (permission_status) { | 93 switch (permission_status) { |
89 case blink::mojom::PermissionStatus::GRANTED: | 94 case blink::mojom::PermissionStatus::GRANTED: |
90 return blink::WebPushPermissionStatusGranted; | 95 return blink::WebPushPermissionStatusGranted; |
91 case blink::mojom::PermissionStatus::DENIED: | 96 case blink::mojom::PermissionStatus::DENIED: |
92 return blink::WebPushPermissionStatusDenied; | 97 return blink::WebPushPermissionStatusDenied; |
93 case blink::mojom::PermissionStatus::ASK: | 98 case blink::mojom::PermissionStatus::ASK: |
94 return blink::WebPushPermissionStatusPrompt; | 99 return blink::WebPushPermissionStatusPrompt; |
95 default: | |
96 NOTREACHED(); | |
97 return blink::WebPushPermissionStatusDenied; | |
98 } | 100 } |
| 101 NOTREACHED(); |
| 102 return blink::WebPushPermissionStatusDenied; |
| 103 } |
| 104 |
| 105 content::PushUnregistrationStatus ToUnregisterStatus( |
| 106 InstanceID::Result result) { |
| 107 switch (result) { |
| 108 case InstanceID::SUCCESS: |
| 109 return content::PUSH_UNREGISTRATION_STATUS_SUCCESS_UNREGISTERED; |
| 110 case InstanceID::INVALID_PARAMETER: |
| 111 case InstanceID::DISABLED: |
| 112 case InstanceID::SERVER_ERROR: |
| 113 case InstanceID::UNKNOWN_ERROR: |
| 114 return content::PUSH_UNREGISTRATION_STATUS_PENDING_SERVICE_ERROR; |
| 115 case InstanceID::ASYNC_OPERATION_PENDING: |
| 116 case InstanceID::NETWORK_ERROR: |
| 117 return content::PUSH_UNREGISTRATION_STATUS_PENDING_NETWORK_ERROR; |
| 118 } |
| 119 NOTREACHED(); |
| 120 return content::PUSH_UNREGISTRATION_STATUS_SERVICE_NOT_AVAILABLE; |
| 121 } |
| 122 |
| 123 content::PushUnregistrationStatus ToUnregisterStatus( |
| 124 gcm::GCMClient::Result gcm_result) { |
| 125 switch (gcm_result) { |
| 126 case gcm::GCMClient::SUCCESS: |
| 127 return content::PUSH_UNREGISTRATION_STATUS_SUCCESS_UNREGISTERED; |
| 128 case gcm::GCMClient::INVALID_PARAMETER: |
| 129 case gcm::GCMClient::GCM_DISABLED: |
| 130 case gcm::GCMClient::SERVER_ERROR: |
| 131 case gcm::GCMClient::UNKNOWN_ERROR: |
| 132 return content::PUSH_UNREGISTRATION_STATUS_PENDING_SERVICE_ERROR; |
| 133 case gcm::GCMClient::ASYNC_OPERATION_PENDING: |
| 134 case gcm::GCMClient::NETWORK_ERROR: |
| 135 case gcm::GCMClient::TTL_EXCEEDED: |
| 136 return content::PUSH_UNREGISTRATION_STATUS_PENDING_NETWORK_ERROR; |
| 137 } |
| 138 NOTREACHED(); |
| 139 return content::PUSH_UNREGISTRATION_STATUS_SERVICE_NOT_AVAILABLE; |
| 140 } |
| 141 |
| 142 void GCMCallbackToUnregisterCallback( |
| 143 const content::PushMessagingService::UnregisterCallback& callback, |
| 144 gcm::GCMClient::Result result) { |
| 145 DCHECK(!callback.is_null()); |
| 146 callback.Run(ToUnregisterStatus(result)); |
99 } | 147 } |
100 | 148 |
101 void UnregisterCallbackToClosure(const base::Closure& closure, | 149 void UnregisterCallbackToClosure(const base::Closure& closure, |
102 content::PushUnregistrationStatus status) { | 150 content::PushUnregistrationStatus status) { |
| 151 DCHECK(!closure.is_null()); |
103 closure.Run(); | 152 closure.Run(); |
104 } | 153 } |
105 | 154 |
106 #if BUILDFLAG(ENABLE_BACKGROUND) | 155 #if BUILDFLAG(ENABLE_BACKGROUND) |
107 bool UseBackgroundMode() { | 156 bool UseBackgroundMode() { |
108 // Note: if push is ever enabled in incognito, the background mode integration | 157 // Note: if push is ever enabled in incognito, the background mode integration |
109 // should not be enabled for it. | 158 // should not be enabled for it. |
110 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | 159 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
111 if (command_line->HasSwitch(switches::kDisablePushApiBackgroundMode)) | 160 if (command_line->HasSwitch(switches::kDisablePushApiBackgroundMode)) |
112 return false; | 161 return false; |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 } | 278 } |
230 #endif | 279 #endif |
231 | 280 |
232 base::Closure message_handled_closure = | 281 base::Closure message_handled_closure = |
233 message_callback_for_testing_.is_null() ? base::Bind(&base::DoNothing) | 282 message_callback_for_testing_.is_null() ? base::Bind(&base::DoNothing) |
234 : message_callback_for_testing_; | 283 : message_callback_for_testing_; |
235 PushMessagingAppIdentifier app_identifier = | 284 PushMessagingAppIdentifier app_identifier = |
236 PushMessagingAppIdentifier::FindByAppId(profile_, app_id); | 285 PushMessagingAppIdentifier::FindByAppId(profile_, app_id); |
237 // Drop message and unregister if app_id was unknown (maybe recently deleted). | 286 // Drop message and unregister if app_id was unknown (maybe recently deleted). |
238 if (app_identifier.is_null()) { | 287 if (app_identifier.is_null()) { |
239 DeliverMessageCallback(app_id, GURL::EmptyGURL(), -1, message, | 288 DeliverMessageCallback(app_id, GURL::EmptyGURL(), |
240 message_handled_closure, | 289 -1 /* kInvalidServiceWorkerRegistrationId */, |
| 290 message, message_handled_closure, |
241 content::PUSH_DELIVERY_STATUS_UNKNOWN_APP_ID); | 291 content::PUSH_DELIVERY_STATUS_UNKNOWN_APP_ID); |
242 return; | 292 return; |
243 } | 293 } |
244 // Drop message and unregister if |origin| has lost push permission. | 294 // Drop message and unregister if |origin| has lost push permission. |
245 if (!IsPermissionSet(app_identifier.origin())) { | 295 if (!IsPermissionSet(app_identifier.origin())) { |
246 DeliverMessageCallback(app_id, app_identifier.origin(), | 296 DeliverMessageCallback(app_id, app_identifier.origin(), |
247 app_identifier.service_worker_registration_id(), | 297 app_identifier.service_worker_registration_id(), |
248 message, message_handled_closure, | 298 message, message_handled_closure, |
249 content::PUSH_DELIVERY_STATUS_PERMISSION_DENIED); | 299 content::PUSH_DELIVERY_STATUS_PERMISSION_DENIED); |
250 return; | 300 return; |
(...skipping 29 matching lines...) Expand all Loading... |
280 | 330 |
281 void PushMessagingServiceImpl::DeliverMessageCallback( | 331 void PushMessagingServiceImpl::DeliverMessageCallback( |
282 const std::string& app_id, | 332 const std::string& app_id, |
283 const GURL& requesting_origin, | 333 const GURL& requesting_origin, |
284 int64_t service_worker_registration_id, | 334 int64_t service_worker_registration_id, |
285 const gcm::IncomingMessage& message, | 335 const gcm::IncomingMessage& message, |
286 const base::Closure& message_handled_closure, | 336 const base::Closure& message_handled_closure, |
287 content::PushDeliveryStatus status) { | 337 content::PushDeliveryStatus status) { |
288 DCHECK_GE(in_flight_message_deliveries_.count(app_id), 1u); | 338 DCHECK_GE(in_flight_message_deliveries_.count(app_id), 1u); |
289 | 339 |
| 340 RecordDeliveryStatus(status); |
| 341 |
290 base::Closure completion_closure = | 342 base::Closure completion_closure = |
291 base::Bind(&PushMessagingServiceImpl::DidHandleMessage, | 343 base::Bind(&PushMessagingServiceImpl::DidHandleMessage, |
292 weak_factory_.GetWeakPtr(), app_id, message_handled_closure); | 344 weak_factory_.GetWeakPtr(), app_id, message_handled_closure); |
293 // The completion_closure should run by default at the end of this function, | 345 // The completion_closure should run by default at the end of this function, |
294 // unless it is explicitly passed to another function. | 346 // unless it is explicitly passed to another function. |
295 base::ScopedClosureRunner completion_closure_runner(completion_closure); | 347 base::ScopedClosureRunner completion_closure_runner(completion_closure); |
296 | 348 |
| 349 // A reason to automatically unsubscribe. UNKNOWN means do not unsubscribe. |
| 350 content::PushUnregistrationReason unsubscribe_reason = |
| 351 content::PUSH_UNREGISTRATION_REASON_UNKNOWN; |
| 352 |
297 // TODO(mvanouwerkerk): Show a warning in the developer console of the | 353 // TODO(mvanouwerkerk): Show a warning in the developer console of the |
298 // Service Worker corresponding to app_id (and/or on an internals page). | 354 // Service Worker corresponding to app_id (and/or on an internals page). |
299 // See https://crbug.com/508516 for options. | 355 // See https://crbug.com/508516 for options. |
300 switch (status) { | 356 switch (status) { |
301 // Call EnforceUserVisibleOnlyRequirements if the message was delivered to | 357 // Call EnforceUserVisibleOnlyRequirements if the message was delivered to |
302 // the Service Worker JavaScript, even if the website's event handler failed | 358 // the Service Worker JavaScript, even if the website's event handler failed |
303 // (to prevent sites deliberately failing in order to avoid having to show | 359 // (to prevent sites deliberately failing in order to avoid having to show |
304 // notifications). | 360 // notifications). |
305 case content::PUSH_DELIVERY_STATUS_SUCCESS: | 361 case content::PUSH_DELIVERY_STATUS_SUCCESS: |
306 case content::PUSH_DELIVERY_STATUS_EVENT_WAITUNTIL_REJECTED: | 362 case content::PUSH_DELIVERY_STATUS_EVENT_WAITUNTIL_REJECTED: |
307 #if defined(ENABLE_NOTIFICATIONS) | 363 #if defined(ENABLE_NOTIFICATIONS) |
308 // Only enforce the user visible requirements if this is currently running | 364 // Only enforce the user visible requirements if this is currently running |
309 // as the delivery callback for the last in-flight message, and silent | 365 // as the delivery callback for the last in-flight message, and silent |
310 // push has not been enabled through a command line flag. | 366 // push has not been enabled through a command line flag. |
311 if (in_flight_message_deliveries_.count(app_id) == 1 && | 367 if (in_flight_message_deliveries_.count(app_id) == 1 && |
312 !base::CommandLine::ForCurrentProcess()->HasSwitch( | 368 !base::CommandLine::ForCurrentProcess()->HasSwitch( |
313 switches::kAllowSilentPush)) { | 369 switches::kAllowSilentPush)) { |
314 notification_manager_.EnforceUserVisibleOnlyRequirements( | 370 notification_manager_.EnforceUserVisibleOnlyRequirements( |
315 requesting_origin, service_worker_registration_id, | 371 requesting_origin, service_worker_registration_id, |
316 completion_closure_runner.Release()); | 372 completion_closure_runner.Release()); |
317 } | 373 } |
318 #endif | 374 #endif |
319 break; | 375 break; |
320 case content::PUSH_DELIVERY_STATUS_SERVICE_WORKER_ERROR: | 376 case content::PUSH_DELIVERY_STATUS_SERVICE_WORKER_ERROR: |
| 377 // Do nothing, and hope the error is transient. |
321 break; | 378 break; |
322 case content::PUSH_DELIVERY_STATUS_UNKNOWN_APP_ID: | 379 case content::PUSH_DELIVERY_STATUS_UNKNOWN_APP_ID: |
| 380 unsubscribe_reason = |
| 381 content::PUSH_UNREGISTRATION_REASON_DELIVERY_UNKNOWN_APP_ID; |
| 382 break; |
323 case content::PUSH_DELIVERY_STATUS_PERMISSION_DENIED: | 383 case content::PUSH_DELIVERY_STATUS_PERMISSION_DENIED: |
| 384 unsubscribe_reason = |
| 385 content::PUSH_UNREGISTRATION_REASON_DELIVERY_PERMISSION_DENIED; |
| 386 break; |
324 case content::PUSH_DELIVERY_STATUS_NO_SERVICE_WORKER: | 387 case content::PUSH_DELIVERY_STATUS_NO_SERVICE_WORKER: |
325 Unsubscribe(app_id, message.sender_id, | 388 unsubscribe_reason = |
326 base::Bind(&UnregisterCallbackToClosure, | 389 content::PUSH_UNREGISTRATION_REASON_DELIVERY_NO_SERVICE_WORKER; |
327 completion_closure_runner.Release())); | |
328 break; | 390 break; |
329 } | 391 } |
330 | 392 |
331 RecordDeliveryStatus(status); | 393 if (unsubscribe_reason != content::PUSH_UNREGISTRATION_REASON_UNKNOWN) { |
| 394 PushMessagingAppIdentifier app_identifier = |
| 395 PushMessagingAppIdentifier::FindByAppId(profile_, app_id); |
| 396 UnsubscribeInternal( |
| 397 unsubscribe_reason, |
| 398 app_identifier.is_null() ? GURL::EmptyGURL() : app_identifier.origin(), |
| 399 app_identifier.is_null() |
| 400 ? -1 /* kInvalidServiceWorkerRegistrationId */ |
| 401 : app_identifier.service_worker_registration_id(), |
| 402 app_id, message.sender_id, |
| 403 base::Bind(&UnregisterCallbackToClosure, |
| 404 completion_closure_runner.Release())); |
| 405 } |
332 } | 406 } |
333 | 407 |
334 void PushMessagingServiceImpl::DidHandleMessage( | 408 void PushMessagingServiceImpl::DidHandleMessage( |
335 const std::string& app_id, | 409 const std::string& app_id, |
336 const base::Closure& message_handled_closure) { | 410 const base::Closure& message_handled_closure) { |
337 auto in_flight_iterator = in_flight_message_deliveries_.find(app_id); | 411 auto in_flight_iterator = in_flight_message_deliveries_.find(app_id); |
338 DCHECK(in_flight_iterator != in_flight_message_deliveries_.end()); | 412 DCHECK(in_flight_iterator != in_flight_message_deliveries_.end()); |
339 | 413 |
340 // Remove a single in-flight delivery for |app_id|. This has to be done using | 414 // Remove a single in-flight delivery for |app_id|. This has to be done using |
341 // an iterator rather than by value, as the latter removes all entries. | 415 // an iterator rather than by value, as the latter removes all entries. |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
384 } | 458 } |
385 | 459 |
386 // Subscribe and GetPermissionStatus methods ----------------------------------- | 460 // Subscribe and GetPermissionStatus methods ----------------------------------- |
387 | 461 |
388 void PushMessagingServiceImpl::SubscribeFromDocument( | 462 void PushMessagingServiceImpl::SubscribeFromDocument( |
389 const GURL& requesting_origin, | 463 const GURL& requesting_origin, |
390 int64_t service_worker_registration_id, | 464 int64_t service_worker_registration_id, |
391 int renderer_id, | 465 int renderer_id, |
392 int render_frame_id, | 466 int render_frame_id, |
393 const content::PushSubscriptionOptions& options, | 467 const content::PushSubscriptionOptions& options, |
394 const content::PushMessagingService::RegisterCallback& callback) { | 468 const RegisterCallback& callback) { |
395 PushMessagingAppIdentifier app_identifier = | 469 PushMessagingAppIdentifier app_identifier = |
396 PushMessagingAppIdentifier::Generate(requesting_origin, | 470 PushMessagingAppIdentifier::Generate(requesting_origin, |
397 service_worker_registration_id); | 471 service_worker_registration_id); |
398 | 472 |
399 if (push_subscription_count_ + pending_push_subscription_count_ >= | 473 if (push_subscription_count_ + pending_push_subscription_count_ >= |
400 kMaxRegistrations) { | 474 kMaxRegistrations) { |
401 SubscribeEndWithError(callback, | 475 SubscribeEndWithError(callback, |
402 content::PUSH_REGISTRATION_STATUS_LIMIT_REACHED); | 476 content::PUSH_REGISTRATION_STATUS_LIMIT_REACHED); |
403 return; | 477 return; |
404 } | 478 } |
(...skipping 20 matching lines...) Expand all Loading... |
425 requesting_origin, true /* user_gesture */, | 499 requesting_origin, true /* user_gesture */, |
426 base::Bind(&PushMessagingServiceImpl::DoSubscribe, | 500 base::Bind(&PushMessagingServiceImpl::DoSubscribe, |
427 weak_factory_.GetWeakPtr(), app_identifier, options, | 501 weak_factory_.GetWeakPtr(), app_identifier, options, |
428 callback)); | 502 callback)); |
429 } | 503 } |
430 | 504 |
431 void PushMessagingServiceImpl::SubscribeFromWorker( | 505 void PushMessagingServiceImpl::SubscribeFromWorker( |
432 const GURL& requesting_origin, | 506 const GURL& requesting_origin, |
433 int64_t service_worker_registration_id, | 507 int64_t service_worker_registration_id, |
434 const content::PushSubscriptionOptions& options, | 508 const content::PushSubscriptionOptions& options, |
435 const content::PushMessagingService::RegisterCallback& register_callback) { | 509 const RegisterCallback& register_callback) { |
436 PushMessagingAppIdentifier app_identifier = | 510 PushMessagingAppIdentifier app_identifier = |
437 PushMessagingAppIdentifier::Generate(requesting_origin, | 511 PushMessagingAppIdentifier::Generate(requesting_origin, |
438 service_worker_registration_id); | 512 service_worker_registration_id); |
439 | 513 |
440 if (push_subscription_count_ + pending_push_subscription_count_ >= | 514 if (push_subscription_count_ + pending_push_subscription_count_ >= |
441 kMaxRegistrations) { | 515 kMaxRegistrations) { |
442 SubscribeEndWithError(register_callback, | 516 SubscribeEndWithError(register_callback, |
443 content::PUSH_REGISTRATION_STATUS_LIMIT_REACHED); | 517 content::PUSH_REGISTRATION_STATUS_LIMIT_REACHED); |
444 return; | 518 return; |
445 } | 519 } |
(...skipping 24 matching lines...) Expand all Loading... |
470 content::PermissionType::PUSH_MESSAGING, origin, origin)); | 544 content::PermissionType::PUSH_MESSAGING, origin, origin)); |
471 } | 545 } |
472 | 546 |
473 bool PushMessagingServiceImpl::SupportNonVisibleMessages() { | 547 bool PushMessagingServiceImpl::SupportNonVisibleMessages() { |
474 return false; | 548 return false; |
475 } | 549 } |
476 | 550 |
477 void PushMessagingServiceImpl::DoSubscribe( | 551 void PushMessagingServiceImpl::DoSubscribe( |
478 const PushMessagingAppIdentifier& app_identifier, | 552 const PushMessagingAppIdentifier& app_identifier, |
479 const content::PushSubscriptionOptions& options, | 553 const content::PushSubscriptionOptions& options, |
480 const content::PushMessagingService::RegisterCallback& register_callback, | 554 const RegisterCallback& register_callback, |
481 blink::mojom::PermissionStatus permission_status) { | 555 blink::mojom::PermissionStatus permission_status) { |
482 if (permission_status != blink::mojom::PermissionStatus::GRANTED) { | 556 if (permission_status != blink::mojom::PermissionStatus::GRANTED) { |
483 SubscribeEndWithError(register_callback, | 557 SubscribeEndWithError(register_callback, |
484 content::PUSH_REGISTRATION_STATUS_PERMISSION_DENIED); | 558 content::PUSH_REGISTRATION_STATUS_PERMISSION_DENIED); |
485 return; | 559 return; |
486 } | 560 } |
487 | 561 |
488 IncreasePushSubscriptionCount(1, true /* is_pending */); | 562 IncreasePushSubscriptionCount(1, true /* is_pending */); |
489 | 563 |
490 GetInstanceIDDriver() | 564 GetInstanceIDDriver() |
491 ->GetInstanceID(app_identifier.app_id()) | 565 ->GetInstanceID(app_identifier.app_id()) |
492 ->GetToken(NormalizeSenderInfo(options.sender_info), kGCMScope, | 566 ->GetToken(NormalizeSenderInfo(options.sender_info), kGCMScope, |
493 std::map<std::string, std::string>() /* options */, | 567 std::map<std::string, std::string>() /* options */, |
494 base::Bind(&PushMessagingServiceImpl::DidSubscribe, | 568 base::Bind(&PushMessagingServiceImpl::DidSubscribe, |
495 weak_factory_.GetWeakPtr(), app_identifier, | 569 weak_factory_.GetWeakPtr(), app_identifier, |
496 options.sender_info, register_callback)); | 570 options.sender_info, register_callback)); |
497 } | 571 } |
498 | 572 |
499 void PushMessagingServiceImpl::SubscribeEnd( | 573 void PushMessagingServiceImpl::SubscribeEnd( |
500 const content::PushMessagingService::RegisterCallback& callback, | 574 const RegisterCallback& callback, |
501 const std::string& subscription_id, | 575 const std::string& subscription_id, |
502 const std::vector<uint8_t>& p256dh, | 576 const std::vector<uint8_t>& p256dh, |
503 const std::vector<uint8_t>& auth, | 577 const std::vector<uint8_t>& auth, |
504 content::PushRegistrationStatus status) { | 578 content::PushRegistrationStatus status) { |
505 callback.Run(subscription_id, p256dh, auth, status); | 579 callback.Run(subscription_id, p256dh, auth, status); |
506 } | 580 } |
507 | 581 |
508 void PushMessagingServiceImpl::SubscribeEndWithError( | 582 void PushMessagingServiceImpl::SubscribeEndWithError( |
509 const content::PushMessagingService::RegisterCallback& callback, | 583 const RegisterCallback& callback, |
510 content::PushRegistrationStatus status) { | 584 content::PushRegistrationStatus status) { |
511 SubscribeEnd(callback, std::string() /* subscription_id */, | 585 SubscribeEnd(callback, std::string() /* subscription_id */, |
512 std::vector<uint8_t>() /* p256dh */, | 586 std::vector<uint8_t>() /* p256dh */, |
513 std::vector<uint8_t>() /* auth */, status); | 587 std::vector<uint8_t>() /* auth */, status); |
514 } | 588 } |
515 | 589 |
516 void PushMessagingServiceImpl::DidSubscribe( | 590 void PushMessagingServiceImpl::DidSubscribe( |
517 const PushMessagingAppIdentifier& app_identifier, | 591 const PushMessagingAppIdentifier& app_identifier, |
518 const std::string& sender_id, | 592 const std::string& sender_id, |
519 const content::PushMessagingService::RegisterCallback& callback, | 593 const RegisterCallback& callback, |
520 const std::string& subscription_id, | 594 const std::string& subscription_id, |
521 InstanceID::Result result) { | 595 InstanceID::Result result) { |
522 DecreasePushSubscriptionCount(1, true /* was_pending */); | 596 DecreasePushSubscriptionCount(1, true /* was_pending */); |
523 | 597 |
524 content::PushRegistrationStatus status = | 598 content::PushRegistrationStatus status = |
525 content::PUSH_REGISTRATION_STATUS_SERVICE_ERROR; | 599 content::PUSH_REGISTRATION_STATUS_SERVICE_ERROR; |
526 | 600 |
527 switch (result) { | 601 switch (result) { |
528 case InstanceID::SUCCESS: | 602 case InstanceID::SUCCESS: |
529 // Make sure that this subscription has associated encryption keys prior | 603 // Make sure that this subscription has associated encryption keys prior |
(...skipping 17 matching lines...) Expand all Loading... |
547 case InstanceID::NETWORK_ERROR: | 621 case InstanceID::NETWORK_ERROR: |
548 status = content::PUSH_REGISTRATION_STATUS_NETWORK_ERROR; | 622 status = content::PUSH_REGISTRATION_STATUS_NETWORK_ERROR; |
549 break; | 623 break; |
550 } | 624 } |
551 | 625 |
552 SubscribeEndWithError(callback, status); | 626 SubscribeEndWithError(callback, status); |
553 } | 627 } |
554 | 628 |
555 void PushMessagingServiceImpl::DidSubscribeWithEncryptionInfo( | 629 void PushMessagingServiceImpl::DidSubscribeWithEncryptionInfo( |
556 const PushMessagingAppIdentifier& app_identifier, | 630 const PushMessagingAppIdentifier& app_identifier, |
557 const content::PushMessagingService::RegisterCallback& callback, | 631 const RegisterCallback& callback, |
558 const std::string& subscription_id, | 632 const std::string& subscription_id, |
559 const std::string& p256dh, | 633 const std::string& p256dh, |
560 const std::string& auth_secret) { | 634 const std::string& auth_secret) { |
561 if (p256dh.empty()) { | 635 if (p256dh.empty()) { |
562 SubscribeEndWithError( | 636 SubscribeEndWithError( |
563 callback, content::PUSH_REGISTRATION_STATUS_PUBLIC_KEY_UNAVAILABLE); | 637 callback, content::PUSH_REGISTRATION_STATUS_PUBLIC_KEY_UNAVAILABLE); |
564 return; | 638 return; |
565 } | 639 } |
566 | 640 |
567 app_identifier.PersistToPrefs(profile_); | 641 app_identifier.PersistToPrefs(profile_); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
603 callback.Run(success, std::vector<uint8_t>(p256dh.begin(), p256dh.end()), | 677 callback.Run(success, std::vector<uint8_t>(p256dh.begin(), p256dh.end()), |
604 std::vector<uint8_t>(auth_secret.begin(), auth_secret.end())); | 678 std::vector<uint8_t>(auth_secret.begin(), auth_secret.end())); |
605 } | 679 } |
606 | 680 |
607 // Unsubscribe methods --------------------------------------------------------- | 681 // Unsubscribe methods --------------------------------------------------------- |
608 | 682 |
609 void PushMessagingServiceImpl::Unsubscribe( | 683 void PushMessagingServiceImpl::Unsubscribe( |
610 const GURL& requesting_origin, | 684 const GURL& requesting_origin, |
611 int64_t service_worker_registration_id, | 685 int64_t service_worker_registration_id, |
612 const std::string& sender_id, | 686 const std::string& sender_id, |
613 const content::PushMessagingService::UnregisterCallback& callback) { | 687 const UnregisterCallback& callback) { |
614 PushMessagingAppIdentifier app_identifier = | 688 PushMessagingAppIdentifier app_identifier = |
615 PushMessagingAppIdentifier::FindByServiceWorker( | 689 PushMessagingAppIdentifier::FindByServiceWorker( |
616 profile_, requesting_origin, service_worker_registration_id); | 690 profile_, requesting_origin, service_worker_registration_id); |
617 if (app_identifier.is_null()) { | 691 |
| 692 UnsubscribeInternal( |
| 693 content::PUSH_UNREGISTRATION_REASON_JAVASCRIPT_API, requesting_origin, |
| 694 service_worker_registration_id, |
| 695 app_identifier.is_null() ? std::string() : app_identifier.app_id(), |
| 696 sender_id, callback); |
| 697 } |
| 698 |
| 699 void PushMessagingServiceImpl::UnsubscribeInternal( |
| 700 content::PushUnregistrationReason reason, |
| 701 const GURL& origin, |
| 702 int64_t service_worker_registration_id, |
| 703 const std::string& app_id, |
| 704 const std::string& sender_id, |
| 705 const UnregisterCallback& callback) { |
| 706 DCHECK(!app_id.empty() || (!origin.is_empty() && |
| 707 service_worker_registration_id != |
| 708 -1 /* kInvalidServiceWorkerRegistrationId */)) |
| 709 << "Need an app_id and/or origin+service_worker_registration_id"; |
| 710 |
| 711 RecordUnsubscribeReason(reason); |
| 712 |
| 713 if (origin.is_empty() || |
| 714 service_worker_registration_id == |
| 715 -1 /* kInvalidServiceWorkerRegistrationId */) { |
| 716 // Can't clear Service Worker database. |
| 717 DidClearPushSubscriptionId(reason, app_id, sender_id, callback); |
| 718 return; |
| 719 } |
| 720 ClearPushSubscriptionId( |
| 721 profile_, origin, service_worker_registration_id, |
| 722 base::Bind(&PushMessagingServiceImpl::DidClearPushSubscriptionId, |
| 723 weak_factory_.GetWeakPtr(), reason, app_id, sender_id, |
| 724 callback)); |
| 725 } |
| 726 |
| 727 void PushMessagingServiceImpl::DidClearPushSubscriptionId( |
| 728 content::PushUnregistrationReason reason, |
| 729 const std::string& app_id, |
| 730 const std::string& sender_id, |
| 731 const UnregisterCallback& callback) { |
| 732 if (app_id.empty()) { |
| 733 // Without an |app_id|, we can neither delete the subscription from the |
| 734 // PushMessagingAppIdentifier map, nor unsubscribe with the GCM Driver. |
618 callback.Run( | 735 callback.Run( |
619 content::PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED); | 736 content::PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED); |
620 return; | 737 return; |
621 } | 738 } |
622 | 739 |
623 Unsubscribe(app_identifier.app_id(), sender_id, callback); | |
624 } | |
625 | |
626 void PushMessagingServiceImpl::Unsubscribe( | |
627 const std::string& app_id, | |
628 const std::string& sender_id, | |
629 const content::PushMessagingService::UnregisterCallback& callback) { | |
630 // Delete the mapping for this app_id, to guarantee that no messages get | 740 // Delete the mapping for this app_id, to guarantee that no messages get |
631 // delivered in future (even if unregistration fails). | 741 // delivered in future (even if unregistration fails). |
632 // TODO(johnme): Instead of deleting these app ids, store them elsewhere, and | 742 // TODO(johnme): Instead of deleting these app ids, store them elsewhere, and |
633 // retry unregistration if it fails due to network errors (crbug.com/465399). | 743 // retry unregistration if it fails due to network errors (crbug.com/465399). |
634 PushMessagingAppIdentifier app_identifier = | 744 PushMessagingAppIdentifier app_identifier = |
635 PushMessagingAppIdentifier::FindByAppId(profile_, app_id); | 745 PushMessagingAppIdentifier::FindByAppId(profile_, app_id); |
636 bool was_subscribed = !app_identifier.is_null(); | 746 bool was_subscribed = !app_identifier.is_null(); |
637 if (was_subscribed) | 747 if (was_subscribed) |
638 app_identifier.DeleteFromPrefs(profile_); | 748 app_identifier.DeleteFromPrefs(profile_); |
639 | 749 |
640 if (PushMessagingAppIdentifier::UseInstanceID(app_id)) { | 750 if (PushMessagingAppIdentifier::UseInstanceID(app_id)) { |
641 GetInstanceIDDriver()->GetInstanceID(app_id)->DeleteID(base::Bind( | 751 GetInstanceIDDriver()->GetInstanceID(app_id)->DeleteID(base::Bind( |
642 &PushMessagingServiceImpl::DidDeleteID, weak_factory_.GetWeakPtr(), | 752 &PushMessagingServiceImpl::DidDeleteID, weak_factory_.GetWeakPtr(), |
643 app_id, was_subscribed, callback)); | 753 app_id, was_subscribed, callback)); |
| 754 |
644 } else { | 755 } else { |
645 auto unregister_callback = | 756 auto unregister_callback = |
646 base::Bind(&PushMessagingServiceImpl::DidUnsubscribe, | 757 base::Bind(&GCMCallbackToUnregisterCallback, |
647 weak_factory_.GetWeakPtr(), was_subscribed, callback); | 758 base::Bind(&PushMessagingServiceImpl::DidUnsubscribe, |
| 759 weak_factory_.GetWeakPtr(), |
| 760 std::string() /* app_id_when_instance_id */, |
| 761 was_subscribed, callback)); |
648 #if defined(OS_ANDROID) | 762 #if defined(OS_ANDROID) |
649 // On Android the backend is different, and requires the original sender_id. | 763 // On Android the backend is different, and requires the original sender_id. |
650 // UnsubscribeBecausePermissionRevoked sometimes calls us with an empty one. | 764 // UnsubscribeBecausePermissionRevoked sometimes calls us with an empty one. |
651 if (sender_id.empty()) { | 765 if (sender_id.empty()) { |
652 unregister_callback.Run(gcm::GCMClient::INVALID_PARAMETER); | 766 unregister_callback.Run(gcm::GCMClient::INVALID_PARAMETER); |
653 } else { | 767 } else { |
654 GetGCMDriver()->UnregisterWithSenderId( | 768 GetGCMDriver()->UnregisterWithSenderId( |
655 app_id, NormalizeSenderInfo(sender_id), unregister_callback); | 769 app_id, NormalizeSenderInfo(sender_id), unregister_callback); |
656 } | 770 } |
657 #else | 771 #else |
658 GetGCMDriver()->Unregister(app_id, unregister_callback); | 772 GetGCMDriver()->Unregister(app_id, unregister_callback); |
659 #endif | 773 #endif |
660 } | 774 } |
661 } | 775 } |
662 | 776 |
663 void PushMessagingServiceImpl::DidDeleteID( | 777 void PushMessagingServiceImpl::DidDeleteID(const std::string& app_id, |
664 const std::string& app_id, | 778 bool was_subscribed, |
665 bool was_subscribed, | 779 const UnregisterCallback& callback, |
666 const content::PushMessagingService::UnregisterCallback& callback, | 780 InstanceID::Result result) { |
667 InstanceID::Result result) { | 781 // DidUnsubscribe must be run asynchronously when passing a non-empty |
668 // DidUnsubscribeInstanceID must be run asynchronously, since it calls | 782 // |app_id_when_instance_id|, since it calls |
669 // InstanceIDDriver::RemoveInstanceID which deletes the InstanceID itself. | 783 // InstanceIDDriver::RemoveInstanceID which deletes the InstanceID itself. |
670 // Calling that immediately would cause a use-after-free in our caller. | 784 // Calling that immediately would cause a use-after-free in our caller. |
671 base::ThreadTaskRunnerHandle::Get()->PostTask( | 785 base::ThreadTaskRunnerHandle::Get()->PostTask( |
672 FROM_HERE, base::Bind(&PushMessagingServiceImpl::DidUnsubscribeInstanceID, | 786 FROM_HERE, base::Bind(&PushMessagingServiceImpl::DidUnsubscribe, |
673 weak_factory_.GetWeakPtr(), app_id, was_subscribed, | 787 weak_factory_.GetWeakPtr(), app_id, was_subscribed, |
674 callback, result)); | 788 callback, ToUnregisterStatus(result))); |
675 } | 789 } |
676 | 790 |
677 void PushMessagingServiceImpl::DidUnsubscribeInstanceID( | 791 void PushMessagingServiceImpl::DidUnsubscribe( |
678 const std::string& app_id, | 792 const std::string& app_id_when_instance_id, |
679 bool was_subscribed, | 793 bool was_subscribed, |
680 const content::PushMessagingService::UnregisterCallback& callback, | 794 const UnregisterCallback& callback, |
681 InstanceID::Result result) { | 795 content::PushUnregistrationStatus status) { |
682 GetInstanceIDDriver()->RemoveInstanceID(app_id); | 796 if (!app_id_when_instance_id.empty()) |
683 | 797 GetInstanceIDDriver()->RemoveInstanceID(app_id_when_instance_id); |
684 if (was_subscribed) | |
685 DecreasePushSubscriptionCount(1, false /* was_pending */); | |
686 | 798 |
687 DCHECK(!callback.is_null()); | 799 DCHECK(!callback.is_null()); |
688 | 800 |
689 if (!was_subscribed) { | 801 if (was_subscribed) { |
| 802 DecreasePushSubscriptionCount(1, false /* was_pending */); |
| 803 callback.Run(status); |
| 804 } else { |
| 805 // Override status since there was no record of an existing subscription. |
690 callback.Run( | 806 callback.Run( |
691 content::PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED); | 807 content::PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED); |
692 return; | |
693 } | |
694 switch (result) { | |
695 case InstanceID::SUCCESS: | |
696 callback.Run(content::PUSH_UNREGISTRATION_STATUS_SUCCESS_UNREGISTERED); | |
697 break; | |
698 case InstanceID::INVALID_PARAMETER: | |
699 case InstanceID::DISABLED: | |
700 case InstanceID::SERVER_ERROR: | |
701 case InstanceID::UNKNOWN_ERROR: | |
702 callback.Run(content::PUSH_UNREGISTRATION_STATUS_PENDING_SERVICE_ERROR); | |
703 break; | |
704 case InstanceID::ASYNC_OPERATION_PENDING: | |
705 case InstanceID::NETWORK_ERROR: | |
706 callback.Run(content::PUSH_UNREGISTRATION_STATUS_PENDING_NETWORK_ERROR); | |
707 break; | |
708 } | 808 } |
709 } | 809 } |
710 | 810 |
711 void PushMessagingServiceImpl::DidUnsubscribe( | |
712 bool was_subscribed, | |
713 const content::PushMessagingService::UnregisterCallback& callback, | |
714 gcm::GCMClient::Result gcm_result) { | |
715 if (was_subscribed) | |
716 DecreasePushSubscriptionCount(1, false /* was_pending */); | |
717 | |
718 DCHECK(!callback.is_null()); | |
719 | |
720 if (!was_subscribed) { | |
721 callback.Run( | |
722 content::PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED); | |
723 return; | |
724 } | |
725 switch (gcm_result) { | |
726 case gcm::GCMClient::SUCCESS: | |
727 callback.Run(content::PUSH_UNREGISTRATION_STATUS_SUCCESS_UNREGISTERED); | |
728 break; | |
729 case gcm::GCMClient::INVALID_PARAMETER: | |
730 case gcm::GCMClient::GCM_DISABLED: | |
731 case gcm::GCMClient::SERVER_ERROR: | |
732 case gcm::GCMClient::UNKNOWN_ERROR: | |
733 callback.Run(content::PUSH_UNREGISTRATION_STATUS_PENDING_SERVICE_ERROR); | |
734 break; | |
735 case gcm::GCMClient::ASYNC_OPERATION_PENDING: | |
736 case gcm::GCMClient::NETWORK_ERROR: | |
737 case gcm::GCMClient::TTL_EXCEEDED: | |
738 callback.Run(content::PUSH_UNREGISTRATION_STATUS_PENDING_NETWORK_ERROR); | |
739 break; | |
740 } | |
741 } | |
742 | |
743 // OnContentSettingChanged methods --------------------------------------------- | 811 // OnContentSettingChanged methods --------------------------------------------- |
744 | 812 |
745 void PushMessagingServiceImpl::OnContentSettingChanged( | 813 void PushMessagingServiceImpl::OnContentSettingChanged( |
746 const ContentSettingsPattern& primary_pattern, | 814 const ContentSettingsPattern& primary_pattern, |
747 const ContentSettingsPattern& secondary_pattern, | 815 const ContentSettingsPattern& secondary_pattern, |
748 ContentSettingsType content_type, | 816 ContentSettingsType content_type, |
749 std::string resource_identifier) { | 817 std::string resource_identifier) { |
750 if (content_type != CONTENT_SETTINGS_TYPE_NOTIFICATIONS) | 818 if (content_type != CONTENT_SETTINGS_TYPE_NOTIFICATIONS) |
751 return; | 819 return; |
752 | 820 |
(...skipping 27 matching lines...) Expand all Loading... |
780 #if defined(OS_ANDROID) | 848 #if defined(OS_ANDROID) |
781 need_sender_id = | 849 need_sender_id = |
782 !PushMessagingAppIdentifier::UseInstanceID(app_identifier.app_id()); | 850 !PushMessagingAppIdentifier::UseInstanceID(app_identifier.app_id()); |
783 #endif | 851 #endif |
784 if (need_sender_id) { | 852 if (need_sender_id) { |
785 GetSenderId( | 853 GetSenderId( |
786 profile_, app_identifier.origin(), | 854 profile_, app_identifier.origin(), |
787 app_identifier.service_worker_registration_id(), | 855 app_identifier.service_worker_registration_id(), |
788 base::Bind( | 856 base::Bind( |
789 &PushMessagingServiceImpl::UnsubscribeBecausePermissionRevoked, | 857 &PushMessagingServiceImpl::UnsubscribeBecausePermissionRevoked, |
790 weak_factory_.GetWeakPtr(), app_identifier, barrier_closure)); | 858 weak_factory_.GetWeakPtr(), app_identifier, |
| 859 base::Bind(&UnregisterCallbackToClosure, barrier_closure))); |
791 } else { | 860 } else { |
792 UnsubscribeBecausePermissionRevoked( | 861 UnsubscribeInternal( |
793 app_identifier, barrier_closure, "" /* sender_id */, | 862 content::PUSH_UNREGISTRATION_REASON_PERMISSION_REVOKED, |
794 true /* success */, true /* not_found */); | 863 app_identifier.origin(), |
| 864 app_identifier.service_worker_registration_id(), |
| 865 app_identifier.app_id(), std::string() /* sender_id */, |
| 866 base::Bind(&UnregisterCallbackToClosure, barrier_closure)); |
795 } | 867 } |
796 } | 868 } |
797 } | 869 } |
798 | 870 |
799 void PushMessagingServiceImpl::UnsubscribeBecausePermissionRevoked( | 871 void PushMessagingServiceImpl::UnsubscribeBecausePermissionRevoked( |
800 const PushMessagingAppIdentifier& app_identifier, | 872 const PushMessagingAppIdentifier& app_identifier, |
801 const base::Closure& closure, | 873 const UnregisterCallback& callback, |
802 const std::string& sender_id, | 874 const std::string& sender_id, |
803 bool success, | 875 bool success, |
804 bool not_found) { | 876 bool not_found) { |
805 base::Closure barrier_closure = base::BarrierClosure(2, closure); | |
806 | |
807 // Unsubscribe the PushMessagingAppIdentifier with the push service. | 877 // Unsubscribe the PushMessagingAppIdentifier with the push service. |
808 // It's possible for GetSenderId to have failed and sender_id to be empty, if | 878 // It's possible for GetSenderId to have failed and sender_id to be empty, if |
809 // cookies (and the SW database) for an origin got cleared before permissions | 879 // cookies (and the SW database) for an origin got cleared before permissions |
810 // are cleared for the origin. In that case for legacy GCM registrations on | 880 // are cleared for the origin. In that case for legacy GCM registrations on |
811 // Android, Unsubscribe will just delete the app identifier to block future | 881 // Android, Unsubscribe will just delete the app identifier to block future |
812 // messages. | 882 // messages. |
813 // TODO(johnme): Auto-unregister before SW DB is cleared | 883 // TODO(johnme): Auto-unregister before SW DB is cleared (crbug.com/402458). |
814 // (https://crbug.com/402458). | 884 UnsubscribeInternal(content::PUSH_UNREGISTRATION_REASON_PERMISSION_REVOKED, |
815 Unsubscribe(app_identifier.app_id(), sender_id, | 885 app_identifier.origin(), |
816 base::Bind(&UnregisterCallbackToClosure, barrier_closure)); | 886 app_identifier.service_worker_registration_id(), |
817 | 887 app_identifier.app_id(), sender_id, callback); |
818 // Clear the associated service worker push registration id. | |
819 ClearPushSubscriptionID(profile_, app_identifier.origin(), | |
820 app_identifier.service_worker_registration_id(), | |
821 barrier_closure); | |
822 } | 888 } |
823 | 889 |
824 void PushMessagingServiceImpl::SetContentSettingChangedCallbackForTesting( | 890 void PushMessagingServiceImpl::SetContentSettingChangedCallbackForTesting( |
825 const base::Closure& callback) { | 891 const base::Closure& callback) { |
826 content_setting_changed_callback_for_testing_ = callback; | 892 content_setting_changed_callback_for_testing_ = callback; |
827 } | 893 } |
828 | 894 |
829 // KeyedService methods ------------------------------------------------------- | 895 // KeyedService methods ------------------------------------------------------- |
830 | 896 |
831 void PushMessagingServiceImpl::Shutdown() { | 897 void PushMessagingServiceImpl::Shutdown() { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
893 } | 959 } |
894 | 960 |
895 instance_id::InstanceIDDriver* PushMessagingServiceImpl::GetInstanceIDDriver() | 961 instance_id::InstanceIDDriver* PushMessagingServiceImpl::GetInstanceIDDriver() |
896 const { | 962 const { |
897 instance_id::InstanceIDProfileService* instance_id_profile_service = | 963 instance_id::InstanceIDProfileService* instance_id_profile_service = |
898 instance_id::InstanceIDProfileServiceFactory::GetForProfile(profile_); | 964 instance_id::InstanceIDProfileServiceFactory::GetForProfile(profile_); |
899 CHECK(instance_id_profile_service); | 965 CHECK(instance_id_profile_service); |
900 CHECK(instance_id_profile_service->driver()); | 966 CHECK(instance_id_profile_service->driver()); |
901 return instance_id_profile_service->driver(); | 967 return instance_id_profile_service->driver(); |
902 } | 968 } |
OLD | NEW |