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

Unified Diff: chrome/browser/services/gcm/gcm_profile_service.cc

Issue 165993005: [GCM] Make sure GCM checkout logic is invoked when the profile is signed out (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix trybots Created 6 years, 10 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/services/gcm/gcm_profile_service.cc
diff --git a/chrome/browser/services/gcm/gcm_profile_service.cc b/chrome/browser/services/gcm/gcm_profile_service.cc
index b58f7e64029eb3a789dc86920aba86ba043de21c..67dc32bcd1f77bfb423840275c80ad0348d9b9d3 100644
--- a/chrome/browser/services/gcm/gcm_profile_service.cc
+++ b/chrome/browser/services/gcm/gcm_profile_service.cc
@@ -260,6 +260,7 @@ class GCMProfileService::IOWorker
const scoped_refptr<net::URLRequestContextGetter>&
url_request_context_getter);
void Reset();
+ void CheckIn();
void CheckOut();
void Register(const std::string& app_id,
const std::vector<std::string>& sender_ids,
@@ -317,9 +318,7 @@ void GCMProfileService::IOWorker::Initialize(
content::BrowserThread::PostTask(
content::BrowserThread::UI,
FROM_HERE,
- base::Bind(&GCMProfileService::FinishInitializationOnUI,
- service_,
- gcm_client_->IsReady()));
+ base::Bind(&GCMProfileService::FinishInitializationOnUI, service_));
}
void GCMProfileService::IOWorker::Reset() {
@@ -417,11 +416,16 @@ void GCMProfileService::IOWorker::OnGCMReady() {
service_));
}
+void GCMProfileService::IOWorker::CheckIn() {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+
+ gcm_client_->CheckIn();
+}
+
void GCMProfileService::IOWorker::CheckOut() {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
gcm_client_->CheckOut();
- gcm_client_.reset();
}
void GCMProfileService::IOWorker::Register(
@@ -505,15 +509,6 @@ GCMProfileService::~GCMProfileService() {
void GCMProfileService::Initialize(
scoped_ptr<GCMClientFactory> gcm_client_factory) {
- gcm_client_factory_ = gcm_client_factory.Pass();
-
- // This has to be done first since CheckIn depends on it.
- io_worker_ = new IOWorker(weak_ptr_factory_.GetWeakPtr());
-
-#if !defined(OS_ANDROID)
- js_event_router_.reset(new extensions::GcmJsEventRouter(profile_));
-#endif
-
registrar_.Add(this,
chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL,
content::Source<Profile>(profile_));
@@ -528,14 +523,20 @@ void GCMProfileService::Initialize(
chrome:: NOTIFICATION_EXTENSION_UNINSTALLED,
content::Source<Profile>(profile_));
- // In case that the profile has been signed in before GCMProfileService is
- // created.
- SigninManagerBase* manager = SigninManagerFactory::GetForProfile(profile_);
- if (manager) {
- std::string username = manager->GetAuthenticatedUsername();
- if (!username.empty())
- CheckIn(username);
- }
+ // Create and initialize the GCMClient. Note that this does not initiate the
+ // GCM check-in.
+ gcm_client_factory_ = gcm_client_factory.Pass();
+ io_worker_ = new IOWorker(weak_ptr_factory_.GetWeakPtr());
+ scoped_refptr<net::URLRequestContextGetter> url_request_context_getter =
+ profile_->GetRequestContext();
+ content::BrowserThread::PostTask(
+ content::BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&GCMProfileService::IOWorker::Initialize,
+ io_worker_,
+ gcm_client_factory_.get(),
+ profile_->GetPath().Append(chrome::kGCMStoreDirname),
+ url_request_context_getter));
}
void GCMProfileService::Register(const std::string& app_id,
@@ -545,6 +546,9 @@ void GCMProfileService::Register(const std::string& app_id,
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
DCHECK(!app_id.empty() && !sender_ids.empty() && !callback.is_null());
+ // Ensure that check-in has been done.
+ EnsureCheckedIn();
+
// If the profile was not signed in, bail out.
if (username_.empty()) {
callback.Run(std::string(), GCMClient::NOT_SIGNED_IN);
@@ -630,6 +634,9 @@ void GCMProfileService::Send(const std::string& app_id,
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
DCHECK(!app_id.empty() && !receiver_id.empty() && !callback.is_null());
+ // Ensure that check-in has been done.
+ EnsureCheckedIn();
fgorski 2014/02/20 22:18:40 Seems like calling send or receive when will check
jianli 2014/02/21 18:25:11 When a gcm app is running and register/send is cal
+
// If the profile was not signed in, bail out.
if (username_.empty()) {
callback.Run(std::string(), GCMClient::NOT_SIGNED_IN);
@@ -681,11 +688,8 @@ void GCMProfileService::Observe(int type,
switch (type) {
case chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL: {
- const GoogleServiceSigninSuccessDetails* signin_details =
- content::Details<GoogleServiceSigninSuccessDetails>(details).ptr();
- // This could be called multiple times when the password changed.
- if (username_ != signin_details->username)
- CheckIn(signin_details->username);
+ if (IsGCMChannelEnabled())
+ EnsureCheckedIn();
break;
}
case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT:
@@ -694,44 +698,66 @@ void GCMProfileService::Observe(int type,
case chrome::NOTIFICATION_PROFILE_DESTROYED:
ResetGCMClient();
break;
- case chrome:: NOTIFICATION_EXTENSION_UNINSTALLED: {
- extensions::Extension* extension =
- content::Details<extensions::Extension>(details).ptr();
- Unregister(extension->id());
+ case chrome:: NOTIFICATION_EXTENSION_UNINSTALLED:
+ if (!username_.empty()) {
+ extensions::Extension* extension =
+ content::Details<extensions::Extension>(details).ptr();
+ Unregister(extension->id());
+ }
break;
- }
default:
NOTREACHED();
}
}
-void GCMProfileService::CheckIn(const std::string& username) {
- DCHECK(!username.empty() && username_.empty());
+bool GCMProfileService::IsGCMChannelEnabled() const {
+ const base::Value* gcm_enabled_value =
+ profile_->GetPrefs()->GetUserPrefValue(prefs::kGCMChannelEnabled);
+ bool gcm_enabled = false;
+ return gcm_enabled_value &&
+ gcm_enabled_value->GetAsBoolean(&gcm_enabled) &&
+ gcm_enabled;
+}
+
+void GCMProfileService::EnsureCheckedIn() {
+ SigninManagerBase* manager = SigninManagerFactory::GetForProfile(profile_);
+ if (!manager)
+ return;
+ std::string username = manager->GetAuthenticatedUsername();
+ if (username.empty())
+ return;
+
+ // CheckIn could be called more than once when:
+ // 1) The password changes.
+ // 2) Register/send function calls it to ensure CheckIn is done.
+ if (username_ == username)
+ return;
username_ = username;
+#if !defined(OS_ANDROID)
+ if (!js_event_router_)
+ js_event_router_.reset(new extensions::GcmJsEventRouter(profile_));
+#endif
+
DCHECK(!delayed_task_controller_);
delayed_task_controller_.reset(new DelayedTaskController);
- // Load all register apps.
+ // Load all the registered apps.
ReadRegisteredAppIDs();
- // Let the IO thread create and initialize GCMClient.
- scoped_refptr<net::URLRequestContextGetter> url_request_context_getter =
- profile_->GetRequestContext();
+ // Initiate the GCM check-in.
content::BrowserThread::PostTask(
content::BrowserThread::IO,
FROM_HERE,
- base::Bind(&GCMProfileService::IOWorker::Initialize,
- io_worker_,
- gcm_client_factory_.get(),
- profile_->GetPath().Append(chrome::kGCMStoreDirname),
- url_request_context_getter));
+ base::Bind(&GCMProfileService::IOWorker::CheckIn, io_worker_));
}
void GCMProfileService::CheckOut() {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- DCHECK(!username_.empty());
+ // We still proceed with the check-out logic even if the check-in is not
+ // initiated in the current session. This will make sure that all the
+ // persisted data written previously will get purged.
username_.clear();
// Remove persisted data from app's state store.
@@ -742,7 +768,6 @@ void GCMProfileService::CheckOut() {
}
// Remove persisted data from prefs store.
- profile_->GetPrefs()->ClearPref(prefs::kGCMChannelEnabled);
profile_->GetPrefs()->ClearPref(prefs::kGCMRegisteredAppIDs);
gcm_client_ready_ = false;
@@ -888,12 +913,12 @@ void GCMProfileService::MessageSendError(const std::string& app_id,
GetEventRouter(app_id)->OnSendError(app_id, message_id, result);
}
-void GCMProfileService::FinishInitializationOnUI(bool ready) {
+void GCMProfileService::FinishInitializationOnUI() {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- gcm_client_ready_ = ready;
- if (gcm_client_ready_)
- delayed_task_controller_->SetGCMReady();
+ // Initiates the check-in if the rollout signal indicates yes.
+ if (IsGCMChannelEnabled())
+ EnsureCheckedIn();
}
void GCMProfileService::GCMClientReady() {

Powered by Google App Engine
This is Rietveld 408576698