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

Side by Side Diff: chrome/browser/services/gcm/gcm_profile_service.cc

Issue 183923006: [GCM] API update to allow only a single sender in registration (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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/services/gcm/gcm_profile_service.h" 5 #include "chrome/browser/services/gcm/gcm_profile_service.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/base64.h" 10 #include "base/base64.h"
(...skipping 28 matching lines...) Expand all
39 #include "google_apis/gcm/protocol/android_checkin.pb.h" 39 #include "google_apis/gcm/protocol/android_checkin.pb.h"
40 #include "net/url_request/url_request_context_getter.h" 40 #include "net/url_request/url_request_context_getter.h"
41 41
42 using extensions::Extension; 42 using extensions::Extension;
43 43
44 namespace gcm { 44 namespace gcm {
45 45
46 namespace { 46 namespace {
47 47
48 const char kRegistrationKey[] = "gcm.registration"; 48 const char kRegistrationKey[] = "gcm.registration";
49 const char kSendersKey[] = "senders"; 49 const char kSenderKey[] = "sender";
50 const char kRegistrationIDKey[] = "reg_id"; 50 const char kRegistrationIDKey[] = "reg_id";
51 51
52 checkin_proto::ChromeBuildProto_Platform GetPlatform() { 52 checkin_proto::ChromeBuildProto_Platform GetPlatform() {
53 #if defined(OS_WIN) 53 #if defined(OS_WIN)
54 return checkin_proto::ChromeBuildProto_Platform_PLATFORM_WIN; 54 return checkin_proto::ChromeBuildProto_Platform_PLATFORM_WIN;
55 #elif defined(OS_MACOSX) 55 #elif defined(OS_MACOSX)
56 return checkin_proto::ChromeBuildProto_Platform_PLATFORM_MAC; 56 return checkin_proto::ChromeBuildProto_Platform_PLATFORM_MAC;
57 #elif defined(OS_CHROMEOS) 57 #elif defined(OS_CHROMEOS)
58 return checkin_proto::ChromeBuildProto_Platform_PLATFORM_CROS; 58 return checkin_proto::ChromeBuildProto_Platform_PLATFORM_CROS;
59 #elif defined(OS_LINUX) 59 #elif defined(OS_LINUX)
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 // Called on IO thread. 260 // Called on IO thread.
261 void Initialize(scoped_ptr<GCMClientFactory> gcm_client_factory, 261 void Initialize(scoped_ptr<GCMClientFactory> gcm_client_factory,
262 const base::FilePath& store_path, 262 const base::FilePath& store_path,
263 const std::vector<std::string>& account_ids, 263 const std::vector<std::string>& account_ids,
264 const scoped_refptr<net::URLRequestContextGetter>& 264 const scoped_refptr<net::URLRequestContextGetter>&
265 url_request_context_getter); 265 url_request_context_getter);
266 void Reset(); 266 void Reset();
267 void Load(const base::WeakPtr<GCMProfileService>& service); 267 void Load(const base::WeakPtr<GCMProfileService>& service);
268 void CheckOut(); 268 void CheckOut();
269 void Register(const std::string& app_id, 269 void Register(const std::string& app_id,
270 const std::vector<std::string>& sender_ids, 270 const std::string& sender_id,
271 const std::string& cert); 271 const std::string& cert);
272 void Unregister(const std::string& app_id); 272 void Unregister(const std::string& app_id);
273 void Send(const std::string& app_id, 273 void Send(const std::string& app_id,
274 const std::string& receiver_id, 274 const std::string& receiver_id,
275 const GCMClient::OutgoingMessage& message); 275 const GCMClient::OutgoingMessage& message);
276 276
277 // For testing purpose. Can be called from UI thread. Use with care. 277 // For testing purpose. Can be called from UI thread. Use with care.
278 GCMClient* gcm_client_for_testing() const { return gcm_client_.get(); } 278 GCMClient* gcm_client_for_testing() const { return gcm_client_.get(); }
279 279
280 private: 280 private:
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 430 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
431 431
432 gcm_client_->CheckOut(); 432 gcm_client_->CheckOut();
433 433
434 // Note that we still need to keep GCMClient instance alive since the profile 434 // Note that we still need to keep GCMClient instance alive since the profile
435 // might be signed in again. 435 // might be signed in again.
436 } 436 }
437 437
438 void GCMProfileService::IOWorker::Register( 438 void GCMProfileService::IOWorker::Register(
439 const std::string& app_id, 439 const std::string& app_id,
440 const std::vector<std::string>& sender_ids, 440 const std::string& sender_id,
441 const std::string& cert) { 441 const std::string& cert) {
442 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 442 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
443 443
444 gcm_client_->Register(app_id, cert, sender_ids); 444 gcm_client_->Register(app_id, cert, sender_id);
445 } 445 }
446 446
447 void GCMProfileService::IOWorker::Unregister(const std::string& app_id) { 447 void GCMProfileService::IOWorker::Unregister(const std::string& app_id) {
448 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 448 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
449 449
450 gcm_client_->Unregister(app_id); 450 gcm_client_->Unregister(app_id);
451 } 451 }
452 452
453 void GCMProfileService::IOWorker::Send( 453 void GCMProfileService::IOWorker::Send(
454 const std::string& app_id, 454 const std::string& app_id,
455 const std::string& receiver_id, 455 const std::string& receiver_id,
456 const GCMClient::OutgoingMessage& message) { 456 const GCMClient::OutgoingMessage& message) {
457 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 457 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
458 458
459 gcm_client_->Send(app_id, receiver_id, message); 459 gcm_client_->Send(app_id, receiver_id, message);
460 } 460 }
461 461
462 GCMProfileService::RegistrationInfo::RegistrationInfo() { 462 GCMProfileService::RegistrationInfo::RegistrationInfo() {
463 } 463 }
464 464
465 GCMProfileService::RegistrationInfo::~RegistrationInfo() { 465 GCMProfileService::RegistrationInfo::~RegistrationInfo() {
466 } 466 }
467 467
468 bool GCMProfileService::RegistrationInfo::IsValid() const { 468 bool GCMProfileService::RegistrationInfo::IsValid() const {
469 return !sender_ids.empty() && !registration_id.empty(); 469 return !sender_id.empty() && !registration_id.empty();
470 } 470 }
471 471
472 // static 472 // static
473 GCMProfileService::GCMEnabledState GCMProfileService::GetGCMEnabledState( 473 GCMProfileService::GCMEnabledState GCMProfileService::GetGCMEnabledState(
474 Profile* profile) { 474 Profile* profile) {
475 const base::Value* gcm_enabled_value = 475 const base::Value* gcm_enabled_value =
476 profile->GetPrefs()->GetUserPrefValue(prefs::kGCMChannelEnabled); 476 profile->GetPrefs()->GetUserPrefValue(prefs::kGCMChannelEnabled);
477 if (!gcm_enabled_value) 477 if (!gcm_enabled_value)
478 return ENABLED_FOR_APPS; 478 return ENABLED_FOR_APPS;
479 479
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 account_ids, 553 account_ids,
554 url_request_context_getter)); 554 url_request_context_getter));
555 555
556 // Load from the GCM store and initiate the GCM check-in if the rollout signal 556 // Load from the GCM store and initiate the GCM check-in if the rollout signal
557 // indicates yes. 557 // indicates yes.
558 if (GetGCMEnabledState(profile_) == ALWAYS_ENABLED) 558 if (GetGCMEnabledState(profile_) == ALWAYS_ENABLED)
559 EnsureLoaded(); 559 EnsureLoaded();
560 } 560 }
561 561
562 void GCMProfileService::Register(const std::string& app_id, 562 void GCMProfileService::Register(const std::string& app_id,
563 const std::vector<std::string>& sender_ids, 563 const std::string& sender_id,
564 const std::string& cert, 564 const std::string& cert,
565 RegisterCallback callback) { 565 RegisterCallback callback) {
566 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 566 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
567 DCHECK(!app_id.empty() && !sender_ids.empty() && !callback.is_null()); 567 DCHECK(!app_id.empty() && !sender_id.empty() && !callback.is_null());
568 568
569 // Ensure that check-in has been done. 569 // Ensure that check-in has been done.
570 EnsureLoaded(); 570 EnsureLoaded();
571 571
572 // If the profile was not signed in, bail out. 572 // If the profile was not signed in, bail out.
573 if (username_.empty()) { 573 if (username_.empty()) {
574 callback.Run(std::string(), GCMClient::NOT_SIGNED_IN); 574 callback.Run(std::string(), GCMClient::NOT_SIGNED_IN);
575 return; 575 return;
576 } 576 }
577 577
578 // If previous register operation is still in progress, bail out. 578 // If previous register operation is still in progress, bail out.
579 if (register_callbacks_.find(app_id) != register_callbacks_.end()) { 579 if (register_callbacks_.find(app_id) != register_callbacks_.end()) {
580 callback.Run(std::string(), GCMClient::ASYNC_OPERATION_PENDING); 580 callback.Run(std::string(), GCMClient::ASYNC_OPERATION_PENDING);
581 return; 581 return;
582 } 582 }
583 583
584 register_callbacks_[app_id] = callback; 584 register_callbacks_[app_id] = callback;
585 585
586 EnsureAppReady(app_id); 586 EnsureAppReady(app_id);
587 587
588 // Delay the register operation until GCMClient is ready. 588 // Delay the register operation until GCMClient is ready.
589 if (!delayed_task_controller_->CanRunTaskWithoutDelay(app_id)) { 589 if (!delayed_task_controller_->CanRunTaskWithoutDelay(app_id)) {
590 delayed_task_controller_->AddTask( 590 delayed_task_controller_->AddTask(
591 app_id, 591 app_id,
592 base::Bind(&GCMProfileService::DoRegister, 592 base::Bind(&GCMProfileService::DoRegister,
593 weak_ptr_factory_.GetWeakPtr(), 593 weak_ptr_factory_.GetWeakPtr(),
594 app_id, 594 app_id,
595 sender_ids, 595 sender_id,
596 cert)); 596 cert));
597 return; 597 return;
598 } 598 }
599 599
600 DoRegister(app_id, sender_ids, cert); 600 DoRegister(app_id, sender_id, cert);
601 } 601 }
602 602
603 void GCMProfileService::DoRegister(const std::string& app_id, 603 void GCMProfileService::DoRegister(const std::string& app_id,
604 const std::vector<std::string>& sender_ids, 604 const std::string& sender_id,
605 const std::string& cert) { 605 const std::string& cert) {
606 std::map<std::string, RegisterCallback>::iterator callback_iter = 606 std::map<std::string, RegisterCallback>::iterator callback_iter =
607 register_callbacks_.find(app_id); 607 register_callbacks_.find(app_id);
608 if (callback_iter == register_callbacks_.end()) { 608 if (callback_iter == register_callbacks_.end()) {
609 // The callback could have been removed when the app is uninstalled. 609 // The callback could have been removed when the app is uninstalled.
610 return; 610 return;
611 } 611 }
612 612
613 // Normalize the sender IDs by making them sorted.
614 std::vector<std::string> normalized_sender_ids = sender_ids;
615 std::sort(normalized_sender_ids.begin(), normalized_sender_ids.end());
616
617 // If the same sender ids is provided, return the cached registration ID 613 // If the same sender ids is provided, return the cached registration ID
618 // directly. 614 // directly.
619 RegistrationInfoMap::const_iterator registration_info_iter = 615 RegistrationInfoMap::const_iterator registration_info_iter =
620 registration_info_map_.find(app_id); 616 registration_info_map_.find(app_id);
621 if (registration_info_iter != registration_info_map_.end() && 617 if (registration_info_iter != registration_info_map_.end() &&
622 registration_info_iter->second.sender_ids == normalized_sender_ids) { 618 registration_info_iter->second.sender_id == sender_id) {
623 RegisterCallback callback = callback_iter->second; 619 RegisterCallback callback = callback_iter->second;
624 register_callbacks_.erase(callback_iter); 620 register_callbacks_.erase(callback_iter);
625 callback.Run(registration_info_iter->second.registration_id, 621 callback.Run(registration_info_iter->second.registration_id,
626 GCMClient::SUCCESS); 622 GCMClient::SUCCESS);
627 return; 623 return;
628 } 624 }
629 625
630 // Cache the sender IDs. The registration ID will be filled when the 626 // Cache the sender IDs. The registration ID will be filled when the
631 // registration completes. 627 // registration completes.
632 RegistrationInfo registration_info; 628 RegistrationInfo registration_info;
633 registration_info.sender_ids = normalized_sender_ids; 629 registration_info.sender_id = sender_id;
634 registration_info_map_[app_id] = registration_info; 630 registration_info_map_[app_id] = registration_info;
635 631
636 // Save the IDs of all registered apps such that we know what to remove from 632 // Save the IDs of all registered apps such that we know what to remove from
637 // the the app's state store when the profile is signed out. 633 // the the app's state store when the profile is signed out.
638 WriteRegisteredAppIDs(); 634 WriteRegisteredAppIDs();
639 635
640 content::BrowserThread::PostTask( 636 content::BrowserThread::PostTask(
641 content::BrowserThread::IO, 637 content::BrowserThread::IO,
642 FROM_HERE, 638 FROM_HERE,
643 base::Bind(&GCMProfileService::IOWorker::Register, 639 base::Bind(&GCMProfileService::IOWorker::Register,
644 io_worker_, 640 io_worker_,
645 app_id, 641 app_id,
646 normalized_sender_ids, 642 sender_id,
647 cert)); 643 cert));
648 } 644 }
649 645
650 void GCMProfileService::Send(const std::string& app_id, 646 void GCMProfileService::Send(const std::string& app_id,
651 const std::string& receiver_id, 647 const std::string& receiver_id,
652 const GCMClient::OutgoingMessage& message, 648 const GCMClient::OutgoingMessage& message,
653 SendCallback callback) { 649 SendCallback callback) {
654 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 650 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
655 DCHECK(!app_id.empty() && !receiver_id.empty() && !callback.is_null()); 651 DCHECK(!app_id.empty() && !receiver_id.empty() && !callback.is_null());
656 652
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
989 985
990 void GCMProfileService::WriteRegistrationInfo(const std::string& app_id) { 986 void GCMProfileService::WriteRegistrationInfo(const std::string& app_id) {
991 extensions::StateStore* storage = 987 extensions::StateStore* storage =
992 extensions::ExtensionSystem::Get(profile_)->state_store(); 988 extensions::ExtensionSystem::Get(profile_)->state_store();
993 DCHECK(storage); 989 DCHECK(storage);
994 990
995 RegistrationInfoMap::const_iterator registration_info_iter = 991 RegistrationInfoMap::const_iterator registration_info_iter =
996 registration_info_map_.find(app_id); 992 registration_info_map_.find(app_id);
997 if (registration_info_iter == registration_info_map_.end()) 993 if (registration_info_iter == registration_info_map_.end())
998 return; 994 return;
995
999 const RegistrationInfo& registration_info = registration_info_iter->second; 996 const RegistrationInfo& registration_info = registration_info_iter->second;
1000
1001 scoped_ptr<base::ListValue> senders_list(new base::ListValue());
1002 for (std::vector<std::string>::const_iterator senders_iter =
1003 registration_info.sender_ids.begin();
1004 senders_iter != registration_info.sender_ids.end();
1005 ++senders_iter) {
1006 senders_list->AppendString(*senders_iter);
1007 }
1008
1009 scoped_ptr<base::DictionaryValue> registration_info_dict( 997 scoped_ptr<base::DictionaryValue> registration_info_dict(
1010 new base::DictionaryValue()); 998 new base::DictionaryValue());
1011 registration_info_dict->Set(kSendersKey, senders_list.release()); 999 registration_info_dict->SetString(kSenderKey,
jianli 2014/03/03 21:29:31 Do we want to make it be compatible with future mu
fgorski 2014/03/03 23:14:16 Done. Modified the write and read code to simply s
1000 registration_info.sender_id);
1012 registration_info_dict->SetString(kRegistrationIDKey, 1001 registration_info_dict->SetString(kRegistrationIDKey,
1013 registration_info.registration_id); 1002 registration_info.registration_id);
1014 1003
1015 storage->SetExtensionValue( 1004 storage->SetExtensionValue(
1016 app_id, kRegistrationKey, registration_info_dict.PassAs<base::Value>()); 1005 app_id, kRegistrationKey, registration_info_dict.PassAs<base::Value>());
1017 } 1006 }
1018 1007
1019 void GCMProfileService::ReadRegistrationInfo(const std::string& app_id) { 1008 void GCMProfileService::ReadRegistrationInfo(const std::string& app_id) {
1020 delayed_task_controller_->AddApp(app_id); 1009 delayed_task_controller_->AddApp(app_id);
1021 1010
(...skipping 28 matching lines...) Expand all
1050 bool GCMProfileService::ParsePersistedRegistrationInfo( 1039 bool GCMProfileService::ParsePersistedRegistrationInfo(
1051 scoped_ptr<base::Value> value, 1040 scoped_ptr<base::Value> value,
1052 RegistrationInfo* registration_info) { 1041 RegistrationInfo* registration_info) {
1053 base::DictionaryValue* dict = NULL; 1042 base::DictionaryValue* dict = NULL;
1054 if (!value.get() || !value->GetAsDictionary(&dict)) 1043 if (!value.get() || !value->GetAsDictionary(&dict))
1055 return false; 1044 return false;
1056 1045
1057 if (!dict->GetString(kRegistrationIDKey, &registration_info->registration_id)) 1046 if (!dict->GetString(kRegistrationIDKey, &registration_info->registration_id))
1058 return false; 1047 return false;
1059 1048
1060 const base::ListValue* senders_list = NULL; 1049 if (!dict->GetString(kSenderKey, &registration_info->sender_id))
1061 if (!dict->GetList(kSendersKey, &senders_list) || !senders_list->GetSize())
1062 return false; 1050 return false;
1063 for (size_t i = 0; i < senders_list->GetSize(); ++i) {
1064 std::string sender;
1065 if (!senders_list->GetString(i, &sender))
1066 return false;
1067 registration_info->sender_ids.push_back(sender);
1068 }
1069 1051
1070 return true; 1052 return true;
1071 } 1053 }
1072 1054
1073 // static 1055 // static
1074 const char* GCMProfileService::GetPersistentRegisterKeyForTesting() { 1056 const char* GCMProfileService::GetPersistentRegisterKeyForTesting() {
1075 return kRegistrationKey; 1057 return kRegistrationKey;
1076 } 1058 }
1077 1059
1078 } // namespace gcm 1060 } // namespace gcm
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698