diff options
author | pavely@chromium.org <pavely@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-21 22:17:13 +0000 |
---|---|---|
committer | pavely@chromium.org <pavely@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-21 22:17:13 +0000 |
commit | ad3995ca5fe927c846f08e17044e14603d1a8b19 (patch) | |
tree | 28d89cd4ecbe42d00fbfe1f545634934479bb41e | |
parent | 2c9ba710edbc2cc3cd771524ef072a52fdb0d82b (diff) | |
download | chromium_src-ad3995ca5fe927c846f08e17044e14603d1a8b19.zip chromium_src-ad3995ca5fe927c846f08e17044e14603d1a8b19.tar.gz chromium_src-ad3995ca5fe927c846f08e17044e14603d1a8b19.tar.bz2 |
Control invalidations network channel from syncer experiment
- Created new experiment protobuf.
- ProfileSyncService writes value to prefs
- TiclInvalidationService registers for changes to both gcm
enabled and invalidations over GCM pref settings. When prefs
change it decides which channel to use and restarts
invalidator if needed.
BUG=325020
R=zea@chromium.org
Review URL: https://codereview.chromium.org/205333003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@258689 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/invalidation/invalidation_service_factory.cc | 6 | ||||
-rw-r--r-- | chrome/browser/invalidation/ticl_invalidation_service.cc | 46 | ||||
-rw-r--r-- | chrome/browser/invalidation/ticl_invalidation_service.h | 15 | ||||
-rw-r--r-- | chrome/browser/invalidation/ticl_invalidation_service_unittest.cc | 83 | ||||
-rw-r--r-- | chrome/browser/sync/profile_sync_service.cc | 3 | ||||
-rw-r--r-- | chrome/common/pref_names.cc | 5 | ||||
-rw-r--r-- | chrome/common/pref_names.h | 1 | ||||
-rw-r--r-- | sync/internal_api/public/util/experiments.h | 10 | ||||
-rw-r--r-- | sync/internal_api/sync_manager_impl.cc | 12 | ||||
-rw-r--r-- | sync/protocol/experiments_specifics.proto | 6 | ||||
-rw-r--r-- | sync/protocol/proto_value_conversions.cc | 1 |
11 files changed, 177 insertions, 11 deletions
diff --git a/chrome/browser/invalidation/invalidation_service_factory.cc b/chrome/browser/invalidation/invalidation_service_factory.cc index b0907b5..ec5f01f 100644 --- a/chrome/browser/invalidation/invalidation_service_factory.cc +++ b/chrome/browser/invalidation/invalidation_service_factory.cc @@ -18,8 +18,10 @@ #include "chrome/browser/signin/signin_manager.h" #include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" +#include "chrome/common/pref_names.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/signin/core/profile_oauth2_token_service.h" +#include "components/user_prefs/pref_registry_syncable.h" #if defined(OS_ANDROID) #include "chrome/browser/invalidation/invalidation_controller_android.h" @@ -107,6 +109,10 @@ KeyedService* InvalidationServiceFactory::BuildServiceInstanceFor( void InvalidationServiceFactory::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) { + registry->RegisterBooleanPref( + prefs::kInvalidationServiceUseGCMChannel, + false, + user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); InvalidatorStorage::RegisterProfilePrefs(registry); } diff --git a/chrome/browser/invalidation/ticl_invalidation_service.cc b/chrome/browser/invalidation/ticl_invalidation_service.cc index 8da391e..1ecdf4c 100644 --- a/chrome/browser/invalidation/ticl_invalidation_service.cc +++ b/chrome/browser/invalidation/ticl_invalidation_service.cc @@ -6,13 +6,16 @@ #include "base/command_line.h" #include "base/metrics/histogram.h" +#include "base/prefs/pref_service.h" #include "chrome/browser/invalidation/gcm_invalidation_bridge.h" #include "chrome/browser/invalidation/invalidation_auth_provider.h" #include "chrome/browser/invalidation/invalidation_logger.h" #include "chrome/browser/invalidation/invalidation_service_util.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/services/gcm/gcm_profile_service.h" #include "chrome/browser/services/gcm/gcm_profile_service_factory.h" #include "chrome/common/chrome_content_client.h" +#include "chrome/common/pref_names.h" #include "components/signin/core/profile_oauth2_token_service.h" #include "google_apis/gaia/gaia_constants.h" #include "sync/notifier/gcm_network_channel_delegate.h" @@ -64,6 +67,7 @@ TiclInvalidationService::TiclInvalidationService( auth_provider_(auth_provider.Pass()), invalidator_registrar_(new syncer::InvalidatorRegistrar()), request_access_token_backoff_(&kRequestAccessTokenBackoffPolicy), + network_channel_type_(PUSH_CLIENT_CHANNEL), logger_() {} TiclInvalidationService::~TiclInvalidationService() { @@ -80,8 +84,20 @@ void TiclInvalidationService::Init() { invalidator_storage_->SetInvalidatorClientId(GenerateInvalidatorClientId()); } + pref_change_registrar_.Init(profile_->GetPrefs()); + pref_change_registrar_.Add( + prefs::kInvalidationServiceUseGCMChannel, + base::Bind(&TiclInvalidationService::UpdateInvalidationNetworkChannel, + base::Unretained(this))); + pref_change_registrar_.Add( + prefs::kGCMChannelEnabled, + base::Bind(&TiclInvalidationService::UpdateInvalidationNetworkChannel, + base::Unretained(this))); + + UpdateInvalidationNetworkChannel(); + if (IsReadyToStart()) { - StartInvalidator(PUSH_CLIENT_CHANNEL); + StartInvalidator(network_channel_type_); } auth_provider_->AddObserver(this); @@ -195,7 +211,7 @@ void TiclInvalidationService::OnGetTokenSuccess( request_access_token_backoff_.Reset(); access_token_ = access_token; if (!IsStarted() && IsReadyToStart()) { - StartInvalidator(PUSH_CLIENT_CHANNEL); + StartInvalidator(network_channel_type_); } else { UpdateInvalidatorCredentials(); } @@ -235,7 +251,7 @@ void TiclInvalidationService::OnRefreshTokenAvailable( const std::string& account_id) { if (auth_provider_->GetAccountId() == account_id) { if (!IsStarted() && IsReadyToStart()) { - StartInvalidator(PUSH_CLIENT_CHANNEL); + StartInvalidator(network_channel_type_); } } } @@ -346,7 +362,9 @@ void TiclInvalidationService::StartInvalidator( DCHECK(invalidator_storage_); DCHECK(!invalidator_storage_->GetInvalidatorClientId().empty()); - if (access_token_.empty()) { + // Request access token for PushClientChannel. GCMNetworkChannel will request + // access token before sending message to server. + if (network_channel == PUSH_CLIENT_CHANNEL && access_token_.empty()) { DVLOG(1) << "TiclInvalidationService: " << "Deferring start until we have an access token."; @@ -405,6 +423,26 @@ void TiclInvalidationService::StartInvalidator( invalidator_registrar_->GetAllRegisteredIds()); } +void TiclInvalidationService::UpdateInvalidationNetworkChannel() { + InvalidationNetworkChannel network_channel_type = PUSH_CLIENT_CHANNEL; +// For now don't use GCM on iOS. +#if !defined(OS_IOS) + if (profile_->GetPrefs()->GetBoolean( + prefs::kInvalidationServiceUseGCMChannel) && + gcm::GCMProfileService::GetGCMEnabledState(profile_) == + gcm::GCMProfileService::ALWAYS_ENABLED) { + network_channel_type = GCM_NETWORK_CHANNEL; + } +#endif + if (network_channel_type_ == network_channel_type) + return; + network_channel_type_ = network_channel_type; + if (IsStarted()) { + StopInvalidator(); + StartInvalidator(network_channel_type_); + } +} + void TiclInvalidationService::UpdateInvalidatorCredentials() { std::string email = auth_provider_->GetAccountId(); diff --git a/chrome/browser/invalidation/ticl_invalidation_service.h b/chrome/browser/invalidation/ticl_invalidation_service.h index c28e585..17f35d2 100644 --- a/chrome/browser/invalidation/ticl_invalidation_service.h +++ b/chrome/browser/invalidation/ticl_invalidation_service.h @@ -8,6 +8,7 @@ #include <string> #include "base/memory/scoped_ptr.h" +#include "base/prefs/pref_change_registrar.h" #include "base/threading/non_thread_safe.h" #include "base/timer/timer.h" #include "chrome/browser/invalidation/invalidation_auth_provider.h" @@ -39,6 +40,11 @@ class TiclInvalidationService : public base::NonThreadSafe, public InvalidationAuthProvider::Observer, public syncer::InvalidationHandler { public: + enum InvalidationNetworkChannel { + PUSH_CLIENT_CHANNEL = 0, + GCM_NETWORK_CHANNEL = 1 + }; + TiclInvalidationService(scoped_ptr<InvalidationAuthProvider> auth_provider, Profile* profile); virtual ~TiclInvalidationService(); @@ -94,17 +100,14 @@ class TiclInvalidationService : public base::NonThreadSafe, void InitForTest(syncer::Invalidator* invalidator); friend class TiclInvalidationServiceTestDelegate; + friend class TiclInvalidationServiceChannelTest; private: - enum InvalidationNetworkChannel { - PUSH_CLIENT_CHANNEL = 0, - GCM_NETWORK_CHANNEL = 1 - }; - bool IsReadyToStart(); bool IsStarted(); void StartInvalidator(InvalidationNetworkChannel network_channel); + void UpdateInvalidationNetworkChannel(); void UpdateInvalidatorCredentials(); void StopInvalidator(); @@ -125,6 +128,8 @@ class TiclInvalidationService : public base::NonThreadSafe, base::OneShotTimer<TiclInvalidationService> request_access_token_retry_timer_; net::BackoffEntry request_access_token_backoff_; + PrefChangeRegistrar pref_change_registrar_; + InvalidationNetworkChannel network_channel_type_; scoped_ptr<GCMInvalidationBridge> gcm_invalidation_bridge_; // The invalidation logger object we use to record state changes diff --git a/chrome/browser/invalidation/ticl_invalidation_service_unittest.cc b/chrome/browser/invalidation/ticl_invalidation_service_unittest.cc index f86dc5a..3a193bc 100644 --- a/chrome/browser/invalidation/ticl_invalidation_service_unittest.cc +++ b/chrome/browser/invalidation/ticl_invalidation_service_unittest.cc @@ -4,12 +4,15 @@ #include "chrome/browser/invalidation/ticl_invalidation_service.h" +#include "base/prefs/pref_service.h" #include "chrome/browser/invalidation/invalidation_service_factory.h" #include "chrome/browser/invalidation/invalidation_service_test_template.h" #include "chrome/browser/invalidation/profile_invalidation_auth_provider.h" #include "chrome/browser/signin/fake_profile_oauth2_token_service.h" +#include "chrome/browser/signin/fake_signin_manager.h" #include "chrome/browser/signin/signin_manager.h" #include "chrome/browser/signin/signin_manager_factory.h" +#include "chrome/common/pref_names.h" #include "chrome/test/base/testing_profile.h" #include "sync/notifier/fake_invalidation_handler.h" #include "sync/notifier/fake_invalidator.h" @@ -67,4 +70,84 @@ INSTANTIATE_TYPED_TEST_CASE_P( TiclInvalidationServiceTest, InvalidationServiceTest, TiclInvalidationServiceTestDelegate); +class TiclInvalidationServiceChannelTest : public ::testing::Test { + public: + TiclInvalidationServiceChannelTest() {} + virtual ~TiclInvalidationServiceChannelTest() {} + + virtual void SetUp() OVERRIDE { + profile_.reset(new TestingProfile()); + fake_signin_manager_ = static_cast<SigninManagerBase*>( + SigninManagerFactory::GetInstance()->SetTestingFactoryAndUse( + profile_.get(), FakeSigninManagerBase::Build)); + token_service_.reset(new FakeProfileOAuth2TokenService); + + scoped_ptr<InvalidationAuthProvider> auth_provider( + new ProfileInvalidationAuthProvider( + fake_signin_manager_, token_service_.get(), NULL)); + invalidation_service_.reset( + new TiclInvalidationService(auth_provider.Pass(), profile_.get())); + invalidation_service_->Init(); + } + + virtual void TearDown() OVERRIDE { + invalidation_service_->Shutdown(); + } + + TiclInvalidationService::InvalidationNetworkChannel GetNetworkChannel() { + return invalidation_service_->network_channel_type_; + } + + protected: + scoped_ptr<TestingProfile> profile_; + SigninManagerBase* fake_signin_manager_; + scoped_ptr<FakeProfileOAuth2TokenService> token_service_; + scoped_ptr<TiclInvalidationService> invalidation_service_; +}; + +TEST_F(TiclInvalidationServiceChannelTest, ChannelSelectionTest) { + TiclInvalidationService::InvalidationNetworkChannel expected_gcm_channel = + TiclInvalidationService::GCM_NETWORK_CHANNEL; +#if defined(OS_IOS) + expected_gcm_channel = TiclInvalidationService::PUSH_CLIENT_CHANNEL; +#endif + + EXPECT_EQ(TiclInvalidationService::PUSH_CLIENT_CHANNEL, GetNetworkChannel()); + + // If stars allign use GCM channel. + profile_->GetPrefs()->SetBoolean(prefs::kGCMChannelEnabled, true); + profile_->GetPrefs()->SetBoolean(prefs::kInvalidationServiceUseGCMChannel, + true); + EXPECT_EQ(expected_gcm_channel, GetNetworkChannel()); + + // If Invalidation channel setting is not set or says false fall back to push + // channel. + profile_->GetPrefs()->SetBoolean(prefs::kGCMChannelEnabled, true); + + profile_->GetPrefs()->ClearPref(prefs::kInvalidationServiceUseGCMChannel); + EXPECT_EQ(TiclInvalidationService::PUSH_CLIENT_CHANNEL, GetNetworkChannel()); + + profile_->GetPrefs()->SetBoolean(prefs::kInvalidationServiceUseGCMChannel, + false); + EXPECT_EQ(TiclInvalidationService::PUSH_CLIENT_CHANNEL, GetNetworkChannel()); + + // If invalidation channel setting says use GCM but GCM is not ALWAYS_ENABLED + // then fall back to push channel. + profile_->GetPrefs()->SetBoolean(prefs::kInvalidationServiceUseGCMChannel, + false); + + profile_->GetPrefs()->ClearPref(prefs::kGCMChannelEnabled); + EXPECT_EQ(TiclInvalidationService::PUSH_CLIENT_CHANNEL, GetNetworkChannel()); + + profile_->GetPrefs()->SetBoolean(prefs::kGCMChannelEnabled, false); + EXPECT_EQ(TiclInvalidationService::PUSH_CLIENT_CHANNEL, GetNetworkChannel()); + + // If first invalidation setting gets enabled and after that gcm setting gets + // enabled then should still switch to GCM channel. + profile_->GetPrefs()->SetBoolean(prefs::kInvalidationServiceUseGCMChannel, + true); + profile_->GetPrefs()->SetBoolean(prefs::kGCMChannelEnabled, true); + EXPECT_EQ(expected_gcm_channel, GetNetworkChannel()); +} + } // namespace invalidation diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc index 57f6c2c..e68bfb5 100644 --- a/chrome/browser/sync/profile_sync_service.cc +++ b/chrome/browser/sync/profile_sync_service.cc @@ -1022,6 +1022,9 @@ void ProfileSyncService::OnExperimentsChanged( profile()->GetPrefs()->ClearPref(prefs::kGCMChannelEnabled); } + profile()->GetPrefs()->SetBoolean(prefs::kInvalidationServiceUseGCMChannel, + experiments.gcm_invalidations_enabled); + int bookmarks_experiment_state_before = profile_->GetPrefs()->GetInteger( sync_driver::prefs::kEnhancedBookmarksExperimentEnabled); // kEnhancedBookmarksExperiment flag could have values "", "1" and "0". diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index cfdbd72..6953a8a 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc @@ -1835,6 +1835,11 @@ const char kInvalidatorInvalidationState[] = "invalidator.invalidation_state"; // yet. Used to keep invalidation clients in sync in case of a restart. const char kInvalidatorSavedInvalidations[] = "invalidator.saved_invalidations"; +// Boolean indicating that TiclInvalidationService should use GCM channel. +// False or lack of settings means XMPPPushClient channel. +const char kInvalidationServiceUseGCMChannel[] = + "invalidation_service.use_gcm_channel"; + // String the identifies the last user that logged into sync and other // google services. As opposed to kGoogleServicesUsername, this value is not // cleared on signout, but while the user is signed in the two values will diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 3306eb4..545d5c0 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h @@ -612,6 +612,7 @@ extern const char kGoogleServicesPasswordHash[]; extern const char kInvalidatorClientId[]; extern const char kInvalidatorInvalidationState[]; extern const char kInvalidatorSavedInvalidations[]; +extern const char kInvalidationServiceUseGCMChannel[]; extern const char kSignInPromoStartupCount[]; extern const char kSignInPromoUserSkipped[]; diff --git a/sync/internal_api/public/util/experiments.h b/sync/internal_api/public/util/experiments.h index 18a0887..9063cbb 100644 --- a/sync/internal_api/public/util/experiments.h +++ b/sync/internal_api/public/util/experiments.h @@ -15,6 +15,7 @@ const char kFaviconSyncTag[] = "favicon_sync"; const char kPreCommitUpdateAvoidanceTag[] = "pre_commit_update_avoidance"; const char kGCMChannelTag[] = "gcm_channel"; const char kEnhancedBookmarksTag[] = "enhanced_bookmarks"; +const char kGCMInvalidationsTag[] = "gcm_invalidations"; // A structure to hold the enable status of experimental sync features. struct Experiments { @@ -27,13 +28,15 @@ struct Experiments { Experiments() : favicon_sync_limit(200), gcm_channel_state(UNSET), - enhanced_bookmarks_enabled(false) {} + enhanced_bookmarks_enabled(false), + gcm_invalidations_enabled(false) {} bool Matches(const Experiments& rhs) { return (favicon_sync_limit == rhs.favicon_sync_limit && gcm_channel_state == rhs.gcm_channel_state && enhanced_bookmarks_enabled == rhs.enhanced_bookmarks_enabled && - enhanced_bookmarks_ext_id == rhs.enhanced_bookmarks_ext_id); + enhanced_bookmarks_ext_id == rhs.enhanced_bookmarks_ext_id && + gcm_invalidations_enabled == rhs.gcm_invalidations_enabled); } // The number of favicons that a client is permitted to sync. @@ -45,6 +48,9 @@ struct Experiments { // Enable the enhanced bookmarks sync datatype. bool enhanced_bookmarks_enabled; + // Enable invalidations over GCM channel. + bool gcm_invalidations_enabled; + // Enhanced bookmarks extension id. std::string enhanced_bookmarks_ext_id; }; diff --git a/sync/internal_api/sync_manager_impl.cc b/sync/internal_api/sync_manager_impl.cc index 8ecb29f..3b4a1fd 100644 --- a/sync/internal_api/sync_manager_impl.cc +++ b/sync/internal_api/sync_manager_impl.cc @@ -1129,6 +1129,18 @@ bool SyncManagerImpl::ReceivedExperiment(Experiments* experiments) { found_experiment = true; } + ReadNode gcm_invalidations_node(&trans); + if (gcm_invalidations_node.InitByClientTagLookup( + syncer::EXPERIMENTS, syncer::kGCMInvalidationsTag) == + BaseNode::INIT_OK) { + const sync_pb::GcmInvalidationsFlags& gcm_invalidations = + gcm_invalidations_node.GetExperimentsSpecifics().gcm_invalidations(); + if (gcm_invalidations.has_enabled()) { + experiments->gcm_invalidations_enabled = gcm_invalidations.enabled(); + found_experiment = true; + } + } + return found_experiment; } diff --git a/sync/protocol/experiments_specifics.proto b/sync/protocol/experiments_specifics.proto index 790cf02..723fe55 100644 --- a/sync/protocol/experiments_specifics.proto +++ b/sync/protocol/experiments_specifics.proto @@ -50,6 +50,11 @@ message EnhancedBookmarksFlags { optional string extension_id = 2; } +// Flags for enabling GCM channel for invalidations. +message GcmInvalidationsFlags { + optional bool enabled = 1; +} + // Contains one flag or set of related flags. Each node of the experiments type // will have a unique_client_tag identifying which flags it contains. By // convention, the tag name should match the sub-message name. @@ -61,4 +66,5 @@ message ExperimentsSpecifics { optional PreCommitUpdateAvoidanceFlags pre_commit_update_avoidance = 5; optional GcmChannelFlags gcm_channel = 6; optional EnhancedBookmarksFlags enhanced_bookmarks = 7; + optional GcmInvalidationsFlags gcm_invalidations = 8; } diff --git a/sync/protocol/proto_value_conversions.cc b/sync/protocol/proto_value_conversions.cc index 83748faa..496a35d 100644 --- a/sync/protocol/proto_value_conversions.cc +++ b/sync/protocol/proto_value_conversions.cc @@ -503,6 +503,7 @@ base::DictionaryValue* ExperimentsSpecificsToValue( SET(favicon_sync, FaviconSyncFlagsToValue); SET_EXPERIMENT_ENABLED_FIELD(gcm_channel); SET_EXPERIMENT_ENABLED_FIELD(enhanced_bookmarks); + SET_EXPERIMENT_ENABLED_FIELD(gcm_invalidations); return value; } |