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/bind.h" | 10 #include "base/bind.h" |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
204 // "registration_ids": ["FOO", "BAR"], | 204 // "registration_ids": ["FOO", "BAR"], |
205 // "data": { | 205 // "data": { |
206 // "data": "BAZ", | 206 // "data": "BAZ", |
207 // }, | 207 // }, |
208 // "delay_while_idle": true, | 208 // "delay_while_idle": true, |
209 // } | 209 // } |
210 // TODO(johnme): Make sure this is clearly documented for developers. | 210 // TODO(johnme): Make sure this is clearly documented for developers. |
211 std::string data; | 211 std::string data; |
212 // TODO(peter): Message payloads are disabled pending mandatory encryption. | 212 // TODO(peter): Message payloads are disabled pending mandatory encryption. |
213 // https://crbug.com/449184 | 213 // https://crbug.com/449184 |
214 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 214 if (AreMessagePayloadsEnabled()) { |
215 switches::kEnablePushMessagePayload)) { | |
216 gcm::MessageData::const_iterator it = message.data.find("data"); | 215 gcm::MessageData::const_iterator it = message.data.find("data"); |
217 if (it != message.data.end()) | 216 if (it != message.data.end()) |
218 data = it->second; | 217 data = it->second; |
219 } | 218 } |
220 | 219 |
221 content::BrowserContext::DeliverPushMessage( | 220 content::BrowserContext::DeliverPushMessage( |
222 profile_, | 221 profile_, |
223 app_identifier.origin(), | 222 app_identifier.origin(), |
224 app_identifier.service_worker_registration_id(), | 223 app_identifier.service_worker_registration_id(), |
225 data, | 224 data, |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
308 const std::string& message_id) { | 307 const std::string& message_id) { |
309 NOTREACHED() << "The Push API shouldn't have sent messages upstream"; | 308 NOTREACHED() << "The Push API shouldn't have sent messages upstream"; |
310 } | 309 } |
311 | 310 |
312 // GetPushEndpoint method ------------------------------------------------------ | 311 // GetPushEndpoint method ------------------------------------------------------ |
313 | 312 |
314 GURL PushMessagingServiceImpl::GetPushEndpoint() { | 313 GURL PushMessagingServiceImpl::GetPushEndpoint() { |
315 return GURL(std::string(kPushMessagingEndpoint)); | 314 return GURL(std::string(kPushMessagingEndpoint)); |
316 } | 315 } |
317 | 316 |
318 // GetPublicEncryptionKey method ----------------------------------------------- | 317 // GetPublicEncryptionKey methods ---------------------------------------------- |
johnme
2015/07/21 15:37:25
Nit: Ideally this section would be between "Subscr
Peter Beverloo
2015/07/21 15:51:08
Done.
| |
319 | 318 |
320 void PushMessagingServiceImpl::GetPublicEncryptionKey( | 319 void PushMessagingServiceImpl::GetPublicEncryptionKey( |
321 const GURL& origin, | 320 const GURL& origin, |
322 int64_t service_worker_registration_id, | 321 int64_t service_worker_registration_id, |
323 const PushMessagingService::PublicKeyCallback& callback) { | 322 const PushMessagingService::PublicKeyCallback& callback) { |
324 // TODO(peter): Get the public key from the GCM Driver. Right now we have to | 323 // An empty public key will be returned if payloads are not enabled. |
325 // return success=true here, otherwise subscriptions would fail. | 324 if (!AreMessagePayloadsEnabled()) { |
326 callback.Run(true /* success */, std::vector<uint8_t>()); | 325 callback.Run(true /* success */, std::vector<uint8_t>()); |
326 return; | |
327 } | |
328 | |
329 PushMessagingAppIdentifier app_identifier = | |
330 PushMessagingAppIdentifier::FindByServiceWorker( | |
331 profile_, origin, service_worker_registration_id); | |
332 | |
333 DCHECK(!app_identifier.is_null()); | |
334 | |
335 GetGCMDriver()->GetPublicKey( | |
336 app_identifier.app_id(), | |
337 base::Bind(&PushMessagingServiceImpl::DidGetPublicKey, | |
338 weak_factory_.GetWeakPtr(), callback)); | |
339 } | |
340 | |
341 void PushMessagingServiceImpl::DidGetPublicKey( | |
342 const PushMessagingService::PublicKeyCallback& callback, | |
343 const std::string& public_key) const { | |
344 // I/O errors might prevent the GCM Driver from retrieving a key-pair. | |
345 const bool success = !!public_key.size(); | |
346 | |
347 callback.Run(success, std::vector<uint8_t>(public_key.begin(), | |
johnme
2015/07/21 15:37:25
On platforms where char is signed, this might caus
Peter Beverloo
2015/07/21 15:51:08
Ack - yay for protobufs storing any binary data as
| |
348 public_key.end())); | |
327 } | 349 } |
328 | 350 |
329 // Subscribe and GetPermissionStatus methods ----------------------------------- | 351 // Subscribe and GetPermissionStatus methods ----------------------------------- |
330 | 352 |
331 void PushMessagingServiceImpl::SubscribeFromDocument( | 353 void PushMessagingServiceImpl::SubscribeFromDocument( |
332 const GURL& requesting_origin, | 354 const GURL& requesting_origin, |
333 int64 service_worker_registration_id, | 355 int64 service_worker_registration_id, |
334 const std::string& sender_id, | 356 const std::string& sender_id, |
335 int renderer_id, | 357 int renderer_id, |
336 int render_frame_id, | 358 int render_frame_id, |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
442 std::vector<uint8_t>() /* curve25519dh */, status); | 464 std::vector<uint8_t>() /* curve25519dh */, status); |
443 } | 465 } |
444 | 466 |
445 void PushMessagingServiceImpl::DidSubscribe( | 467 void PushMessagingServiceImpl::DidSubscribe( |
446 const PushMessagingAppIdentifier& app_identifier, | 468 const PushMessagingAppIdentifier& app_identifier, |
447 const content::PushMessagingService::RegisterCallback& callback, | 469 const content::PushMessagingService::RegisterCallback& callback, |
448 const std::string& subscription_id, | 470 const std::string& subscription_id, |
449 gcm::GCMClient::Result result) { | 471 gcm::GCMClient::Result result) { |
450 content::PushRegistrationStatus status = | 472 content::PushRegistrationStatus status = |
451 content::PUSH_REGISTRATION_STATUS_SERVICE_ERROR; | 473 content::PUSH_REGISTRATION_STATUS_SERVICE_ERROR; |
452 std::vector<uint8_t> curve25519dh; | |
453 | 474 |
454 switch (result) { | 475 switch (result) { |
455 case gcm::GCMClient::SUCCESS: | 476 case gcm::GCMClient::SUCCESS: |
456 status = content::PUSH_REGISTRATION_STATUS_SUCCESS_FROM_PUSH_SERVICE; | 477 // Do not get a certificate if message payloads have not been enabled. |
457 app_identifier.PersistToPrefs(profile_); | 478 if (!AreMessagePayloadsEnabled()) { |
479 DidSubscribeWithPublicKey( | |
480 app_identifier, callback, subscription_id, | |
481 std::string() /* public_key */); | |
482 return; | |
483 } | |
458 | 484 |
459 // TODO(peter): Hook up getting the keys from the GCM Driver. | 485 // Make sure that this subscription has associated encryption keys prior |
486 // to returning it to the developer - they'll need this information in | |
487 // order to send payloads to the user. | |
488 GetGCMDriver()->GetPublicKey( | |
489 app_identifier.app_id(), | |
490 base::Bind( | |
491 &PushMessagingServiceImpl::DidSubscribeWithPublicKey, | |
492 weak_factory_.GetWeakPtr(), app_identifier, callback, | |
493 subscription_id)); | |
460 | 494 |
461 IncreasePushSubscriptionCount(1, false /* is_pending */); | 495 return; |
462 break; | |
463 case gcm::GCMClient::INVALID_PARAMETER: | 496 case gcm::GCMClient::INVALID_PARAMETER: |
464 case gcm::GCMClient::GCM_DISABLED: | 497 case gcm::GCMClient::GCM_DISABLED: |
465 case gcm::GCMClient::ASYNC_OPERATION_PENDING: | 498 case gcm::GCMClient::ASYNC_OPERATION_PENDING: |
466 case gcm::GCMClient::SERVER_ERROR: | 499 case gcm::GCMClient::SERVER_ERROR: |
467 case gcm::GCMClient::UNKNOWN_ERROR: | 500 case gcm::GCMClient::UNKNOWN_ERROR: |
468 status = content::PUSH_REGISTRATION_STATUS_SERVICE_ERROR; | 501 status = content::PUSH_REGISTRATION_STATUS_SERVICE_ERROR; |
469 break; | 502 break; |
470 case gcm::GCMClient::NETWORK_ERROR: | 503 case gcm::GCMClient::NETWORK_ERROR: |
471 case gcm::GCMClient::TTL_EXCEEDED: | 504 case gcm::GCMClient::TTL_EXCEEDED: |
472 status = content::PUSH_REGISTRATION_STATUS_NETWORK_ERROR; | 505 status = content::PUSH_REGISTRATION_STATUS_NETWORK_ERROR; |
473 break; | 506 break; |
474 } | 507 } |
475 | 508 |
476 SubscribeEnd(callback, subscription_id, curve25519dh, status); | 509 SubscribeEndWithError(callback, status); |
johnme
2015/07/21 15:37:26
Why are you removing the call to `DecreasePushSubs
Peter Beverloo
2015/07/21 15:51:08
Oops - done.
| |
510 } | |
511 | |
512 void PushMessagingServiceImpl::DidSubscribeWithPublicKey( | |
513 const PushMessagingAppIdentifier& app_identifier, | |
514 const content::PushMessagingService::RegisterCallback& callback, | |
515 const std::string& subscription_id, | |
516 const std::string& public_key) { | |
517 if (!public_key.size() && AreMessagePayloadsEnabled()) { | |
518 SubscribeEndWithError( | |
johnme
2015/07/21 15:37:26
You need to call `DecreasePushSubscriptionCount(1,
Peter Beverloo
2015/07/21 15:51:08
Done.
| |
519 callback, content::PUSH_REGISTRATION_STATUS_PUBLIC_KEY_UNAVAILABLE); | |
520 return; | |
521 } | |
522 | |
523 app_identifier.PersistToPrefs(profile_); | |
524 | |
525 IncreasePushSubscriptionCount(1, false /* is_pending */); | |
477 DecreasePushSubscriptionCount(1, true /* was_pending */); | 526 DecreasePushSubscriptionCount(1, true /* was_pending */); |
527 | |
528 SubscribeEnd(callback, subscription_id, | |
529 std::vector<uint8_t>(public_key.begin(), public_key.end()), | |
530 content::PUSH_REGISTRATION_STATUS_SUCCESS_FROM_PUSH_SERVICE); | |
478 } | 531 } |
479 | 532 |
480 void PushMessagingServiceImpl::DidRequestPermission( | 533 void PushMessagingServiceImpl::DidRequestPermission( |
481 const PushMessagingAppIdentifier& app_identifier, | 534 const PushMessagingAppIdentifier& app_identifier, |
482 const std::string& sender_id, | 535 const std::string& sender_id, |
483 const content::PushMessagingService::RegisterCallback& register_callback, | 536 const content::PushMessagingService::RegisterCallback& register_callback, |
484 content::PermissionStatus permission_status) { | 537 content::PermissionStatus permission_status) { |
485 if (permission_status != content::PERMISSION_STATUS_GRANTED) { | 538 if (permission_status != content::PERMISSION_STATUS_GRANTED) { |
486 SubscribeEndWithError(register_callback, | 539 SubscribeEndWithError(register_callback, |
487 content::PUSH_REGISTRATION_STATUS_PERMISSION_DENIED); | 540 content::PUSH_REGISTRATION_STATUS_PERMISSION_DENIED); |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
665 | 718 |
666 // Helper methods -------------------------------------------------------------- | 719 // Helper methods -------------------------------------------------------------- |
667 | 720 |
668 // Assumes user_visible always since this is just meant to check | 721 // Assumes user_visible always since this is just meant to check |
669 // if the permission was previously granted and not revoked. | 722 // if the permission was previously granted and not revoked. |
670 bool PushMessagingServiceImpl::IsPermissionSet(const GURL& origin) { | 723 bool PushMessagingServiceImpl::IsPermissionSet(const GURL& origin) { |
671 return GetPermissionStatus(origin, origin, true /* user_visible */) == | 724 return GetPermissionStatus(origin, origin, true /* user_visible */) == |
672 blink::WebPushPermissionStatusGranted; | 725 blink::WebPushPermissionStatusGranted; |
673 } | 726 } |
674 | 727 |
728 bool PushMessagingServiceImpl::AreMessagePayloadsEnabled() const { | |
729 return base::CommandLine::ForCurrentProcess()->HasSwitch( | |
730 switches::kEnablePushMessagePayload); | |
731 } | |
732 | |
675 gcm::GCMDriver* PushMessagingServiceImpl::GetGCMDriver() const { | 733 gcm::GCMDriver* PushMessagingServiceImpl::GetGCMDriver() const { |
676 gcm::GCMProfileService* gcm_profile_service = | 734 gcm::GCMProfileService* gcm_profile_service = |
677 gcm::GCMProfileServiceFactory::GetForProfile(profile_); | 735 gcm::GCMProfileServiceFactory::GetForProfile(profile_); |
678 CHECK(gcm_profile_service); | 736 CHECK(gcm_profile_service); |
679 CHECK(gcm_profile_service->driver()); | 737 CHECK(gcm_profile_service->driver()); |
680 return gcm_profile_service->driver(); | 738 return gcm_profile_service->driver(); |
681 } | 739 } |
OLD | NEW |