From 9d7e5c0883487bbc0b7dc07485bd02aad29da947 Mon Sep 17 00:00:00 2001 From: "jianli@chromium.org" Date: Wed, 21 May 2014 03:09:03 +0000 Subject: [PATCH] Make GCMProfileService own GCMDriver, instead of deriving from it Also remove several tests related to testing on neutral channel signals. Replacement tests will be added when we switch to starting and stopping GCM on demand in the future patch. BUG=356716 TEST=tests updated TBR=kalman@chromium.org,pavely@chromium.org,arv@chromium.org Review URL: https://codereview.chromium.org/286213003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@271832 0039d316-1c4b-4281-b951-d872f2087c98 --- chrome/browser/extensions/api/gcm/gcm_api.cc | 33 +-- chrome/browser/extensions/api/gcm/gcm_api.h | 9 +- .../browser/extensions/api/gcm/gcm_apitest.cc | 1 - .../extensions/extension_gcm_app_handler.cc | 15 +- .../extensions/extension_gcm_app_handler.h | 3 +- .../extension_gcm_app_handler_unittest.cc | 25 +- .../invalidation/gcm_invalidation_bridge.h | 2 +- .../gcm_invalidation_bridge_unittest.cc | 30 +-- .../invalidation_service_factory.cc | 2 +- .../invalidation/ticl_invalidation_service.h | 2 +- .../ticl_invalidation_service_unittest.cc | 32 +-- ...ticl_profile_settings_provider_unittest.cc | 2 +- .../services/gcm/fake_gcm_profile_service.cc | 135 ++++++++--- .../services/gcm/fake_gcm_profile_service.h | 25 +- chrome/browser/services/gcm/gcm_driver.cc | 95 +++++--- chrome/browser/services/gcm/gcm_driver.h | 57 +++-- .../services/gcm/gcm_driver_unittest.cc | 228 ++++++------------ .../services/gcm/gcm_profile_service.cc | 62 +++-- .../services/gcm/gcm_profile_service.h | 34 ++- .../gcm/gcm_profile_service_factory.cc | 8 +- .../gcm/gcm_profile_service_unittest.cc | 92 ++++--- chrome/browser/sync/profile_sync_service.cc | 7 +- chrome/browser/ui/webui/gcm_internals_ui.cc | 13 +- google_apis/gcm/gcm_client.h | 2 + sync/notifier/gcm_network_channel.cc | 1 + 25 files changed, 456 insertions(+), 459 deletions(-) diff --git a/chrome/browser/extensions/api/gcm/gcm_api.cc b/chrome/browser/extensions/api/gcm/gcm_api.cc index 9134c5ed340fbe..6fd12ec9261e68 100644 --- a/chrome/browser/extensions/api/gcm/gcm_api.cc +++ b/chrome/browser/extensions/api/gcm/gcm_api.cc @@ -13,9 +13,11 @@ #include "base/strings/string_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/services/gcm/gcm_driver.h" #include "chrome/browser/services/gcm/gcm_profile_service.h" #include "chrome/browser/services/gcm/gcm_profile_service_factory.h" #include "chrome/common/extensions/api/gcm.h" +#include "extensions/browser/event_router.h" #include "extensions/common/extension.h" namespace { @@ -28,6 +30,7 @@ const char kGoogleRestrictedPrefix[] = "google"; // Error messages. const char kInvalidParameter[] = "Function was called with invalid parameters."; +const char kGCMDisabled[] = "GCM is currently disabled."; const char kNotSignedIn[] = "Profile was not signed in."; const char kAsyncOperationPending[] = "Asynchronous operation is pending."; @@ -42,6 +45,8 @@ const char* GcmResultToError(gcm::GCMClient::Result result) { return ""; case gcm::GCMClient::INVALID_PARAMETER: return kInvalidParameter; + case gcm::GCMClient::GCM_DISABLED: + return kGCMDisabled; case gcm::GCMClient::NOT_SIGNED_IN: return kNotSignedIn; case gcm::GCMClient::ASYNC_OPERATION_PENDING: @@ -97,9 +102,9 @@ bool GcmApiFunction::IsGcmApiEnabled() const { gcm::GCMProfileService::ALWAYS_DISABLED; } -gcm::GCMProfileService* GcmApiFunction::GCMProfileService() const { +gcm::GCMDriver* GcmApiFunction::GetGCMDriver() const { return gcm::GCMProfileServiceFactory::GetForProfile( - Profile::FromBrowserContext(browser_context())); + Profile::FromBrowserContext(browser_context()))->driver(); } GcmRegisterFunction::GcmRegisterFunction() {} @@ -111,7 +116,7 @@ bool GcmRegisterFunction::DoWork() { api::gcm::Register::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params.get()); - GCMProfileService()->Register( + GetGCMDriver()->Register( GetExtension()->id(), params->sender_ids, base::Bind(&GcmRegisterFunction::CompleteFunctionWithResult, this)); @@ -134,7 +139,7 @@ GcmUnregisterFunction::~GcmUnregisterFunction() {} bool GcmUnregisterFunction::DoWork() { UMA_HISTOGRAM_BOOLEAN("GCM.APICallUnregister", true); - GCMProfileService()->Unregister( + GetGCMDriver()->Unregister( GetExtension()->id(), base::Bind(&GcmUnregisterFunction::CompleteFunctionWithResult, this)); @@ -164,7 +169,7 @@ bool GcmSendFunction::DoWork() { if (params->message.time_to_live.get()) outgoing_message.time_to_live = *params->message.time_to_live; - GCMProfileService()->Send( + GetGCMDriver()->Send( GetExtension()->id(), params->message.destination_id, outgoing_message, @@ -199,19 +204,9 @@ bool GcmSendFunction::ValidateMessageData( } GcmJsEventRouter::GcmJsEventRouter(Profile* profile) : profile_(profile) { - EventRouter* event_router = EventRouter::Get(profile_); - if (!event_router) - return; - - event_router->RegisterObserver(this, api::gcm::OnMessage::kEventName); - event_router->RegisterObserver(this, api::gcm::OnMessagesDeleted::kEventName); - event_router->RegisterObserver(this, api::gcm::OnSendError::kEventName); } GcmJsEventRouter::~GcmJsEventRouter() { - EventRouter* event_router = EventRouter::Get(profile_); - if (event_router) - event_router->UnregisterObserver(this); } void GcmJsEventRouter::OnMessage( @@ -252,12 +247,4 @@ void GcmJsEventRouter::OnSendError( EventRouter::Get(profile_)->DispatchEventToExtension(app_id, event.Pass()); } -void GcmJsEventRouter::OnListenerAdded(const EventListenerInfo& details) { - if (gcm::GCMProfileService::GetGCMEnabledState(profile_) == - gcm::GCMProfileService::ALWAYS_DISABLED) { - return; - } - gcm::GCMProfileServiceFactory::GetForProfile(profile_)->Start(); -} - } // namespace extensions diff --git a/chrome/browser/extensions/api/gcm/gcm_api.h b/chrome/browser/extensions/api/gcm/gcm_api.h index e5447c0ea935cf..4a13a2fd6a8bbf 100644 --- a/chrome/browser/extensions/api/gcm/gcm_api.h +++ b/chrome/browser/extensions/api/gcm/gcm_api.h @@ -6,11 +6,11 @@ #define CHROME_BROWSER_EXTENSIONS_API_GCM_GCM_API_H_ #include "chrome/common/extensions/api/gcm.h" -#include "extensions/browser/event_router.h" #include "extensions/browser/extension_function.h" #include "google_apis/gcm/gcm_client.h" namespace gcm { +class GCMDriver; class GCMProfileService; } // namespace gcm @@ -34,7 +34,7 @@ class GcmApiFunction : public AsyncExtensionFunction { // Checks that the GCM API is enabled. bool IsGcmApiEnabled() const; - gcm::GCMProfileService* GCMProfileService() const; + gcm::GCMDriver* GetGCMDriver() const; }; class GcmRegisterFunction : public GcmApiFunction { @@ -91,7 +91,7 @@ class GcmSendFunction : public GcmApiFunction { bool ValidateMessageData(const gcm::GCMClient::MessageData& data) const; }; -class GcmJsEventRouter : public EventRouter::Observer { +class GcmJsEventRouter { public: explicit GcmJsEventRouter(Profile* profile); @@ -103,9 +103,6 @@ class GcmJsEventRouter : public EventRouter::Observer { void OnSendError(const std::string& app_id, const gcm::GCMClient::SendErrorDetails& send_error_details); - // EventRouter::Observer: - virtual void OnListenerAdded(const EventListenerInfo& details) OVERRIDE; - private: // The application we route the event to is running in context of the // |profile_| and the latter outlives the event router. diff --git a/chrome/browser/extensions/api/gcm/gcm_apitest.cc b/chrome/browser/extensions/api/gcm/gcm_apitest.cc index 70212ab47c13e2..46b02ff67b8223 100644 --- a/chrome/browser/extensions/api/gcm/gcm_apitest.cc +++ b/chrome/browser/extensions/api/gcm/gcm_apitest.cc @@ -13,7 +13,6 @@ #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/ui_test_utils.h" -#include "components/gcm_driver/gcm_client_factory.h" namespace { diff --git a/chrome/browser/extensions/extension_gcm_app_handler.cc b/chrome/browser/extensions/extension_gcm_app_handler.cc index 879a351afddd92..505271aeeaeb20 100644 --- a/chrome/browser/extensions/extension_gcm_app_handler.cc +++ b/chrome/browser/extensions/extension_gcm_app_handler.cc @@ -9,6 +9,7 @@ #include "base/location.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/services/gcm/gcm_driver.h" #include "chrome/browser/services/gcm/gcm_profile_service.h" #include "chrome/browser/services/gcm/gcm_profile_service_factory.h" #include "content/public/browser/notification_details.h" @@ -63,7 +64,7 @@ ExtensionGCMAppHandler::~ExtensionGCMAppHandler() { extension != enabled_extensions.end(); ++extension) { if (IsGCMPermissionEnabled(extension->get())) - GetGCMProfileService()->RemoveAppHandler((*extension)->id()); + GetGCMDriver()->RemoveAppHandler((*extension)->id()); } } @@ -99,7 +100,7 @@ void ExtensionGCMAppHandler::OnExtensionLoaded( content::BrowserContext* browser_context, const Extension* extension) { if (IsGCMPermissionEnabled(extension)) - GetGCMProfileService()->AddAppHandler(extension->id(), this); + GetGCMDriver()->AddAppHandler(extension->id(), this); } void ExtensionGCMAppHandler::OnExtensionUnloaded( @@ -107,7 +108,7 @@ void ExtensionGCMAppHandler::OnExtensionUnloaded( const Extension* extension, UnloadedExtensionInfo::Reason reason) { if (IsGCMPermissionEnabled(extension)) - GetGCMProfileService()->RemoveAppHandler(extension->id()); + GetGCMDriver()->RemoveAppHandler(extension->id()); } void ExtensionGCMAppHandler::Observe( @@ -117,17 +118,17 @@ void ExtensionGCMAppHandler::Observe( DCHECK_EQ(chrome::NOTIFICATION_EXTENSION_UNINSTALLED, type); const Extension* extension = content::Details(details).ptr(); if (IsGCMPermissionEnabled(extension)) { - GetGCMProfileService()->Unregister( + GetGCMDriver()->Unregister( extension->id(), base::Bind(&ExtensionGCMAppHandler::OnUnregisterCompleted, weak_factory_.GetWeakPtr(), extension->id())); - GetGCMProfileService()->RemoveAppHandler(extension->id()); + GetGCMDriver()->RemoveAppHandler(extension->id()); } } -gcm::GCMProfileService* ExtensionGCMAppHandler::GetGCMProfileService() const { - return gcm::GCMProfileServiceFactory::GetForProfile(profile_); +gcm::GCMDriver* ExtensionGCMAppHandler::GetGCMDriver() const { + return gcm::GCMProfileServiceFactory::GetForProfile(profile_)->driver(); } void ExtensionGCMAppHandler::OnUnregisterCompleted( diff --git a/chrome/browser/extensions/extension_gcm_app_handler.h b/chrome/browser/extensions/extension_gcm_app_handler.h index 7b1f0da44c508c..5da91b71d05697 100644 --- a/chrome/browser/extensions/extension_gcm_app_handler.h +++ b/chrome/browser/extensions/extension_gcm_app_handler.h @@ -26,6 +26,7 @@ class BrowserContext; } namespace gcm { +class GCMDriver; class GCMProfileService; } @@ -77,7 +78,7 @@ class ExtensionGCMAppHandler : public gcm::GCMAppHandler, const Extension* extension, UnloadedExtensionInfo::Reason reason) OVERRIDE; - gcm::GCMProfileService* GetGCMProfileService() const; + gcm::GCMDriver* GetGCMDriver() const; // BrowserContextKeyedAPI implementation. static const char* service_name() { return "ExtensionGCMAppHandler"; } diff --git a/chrome/browser/extensions/extension_gcm_app_handler_unittest.cc b/chrome/browser/extensions/extension_gcm_app_handler_unittest.cc index 786f1d9bbf0b0d..81e9c7c88f4f09 100644 --- a/chrome/browser/extensions/extension_gcm_app_handler_unittest.cc +++ b/chrome/browser/extensions/extension_gcm_app_handler_unittest.cc @@ -23,6 +23,7 @@ #include "chrome/browser/services/gcm/fake_gcm_client.h" #include "chrome/browser/services/gcm/fake_gcm_client_factory.h" #include "chrome/browser/services/gcm/fake_signin_manager.h" +#include "chrome/browser/services/gcm/gcm_driver.h" #include "chrome/browser/services/gcm/gcm_profile_service.h" #include "chrome/browser/services/gcm/gcm_profile_service_factory.h" #include "chrome/browser/signin/signin_manager_factory.h" @@ -167,7 +168,10 @@ class ExtensionGCMAppHandlerTest : public testing::Test { public: static KeyedService* BuildGCMProfileService( content::BrowserContext* context) { - return new gcm::GCMProfileService(static_cast(context)); + return new gcm::GCMProfileService( + Profile::FromBrowserContext(context), + scoped_ptr( + new gcm::FakeGCMClientFactory(gcm::FakeGCMClient::NO_DELAY_START))); } ExtensionGCMAppHandlerTest() @@ -209,15 +213,8 @@ class ExtensionGCMAppHandlerTest : public testing::Test { profile()->GetPrefs()->SetBoolean(prefs::kGCMChannelEnabled, true); // Create GCMProfileService that talks with fake GCMClient. - gcm::GCMProfileService* gcm_profile_service = - static_cast( - gcm::GCMProfileServiceFactory::GetInstance()-> - SetTestingFactoryAndUse( - profile(), - &ExtensionGCMAppHandlerTest::BuildGCMProfileService)); - scoped_ptr gcm_client_factory( - new gcm::FakeGCMClientFactory(gcm::FakeGCMClient::NO_DELAY_START)); - gcm_profile_service->Initialize(gcm_client_factory.Pass()); + gcm::GCMProfileServiceFactory::GetInstance()->SetTestingFactoryAndUse( + profile(), &ExtensionGCMAppHandlerTest::BuildGCMProfileService); // Create a fake version of ExtensionGCMAppHandler. gcm_app_handler_.reset(new FakeExtensionGCMAppHandler(profile(), &waiter_)); @@ -288,7 +285,7 @@ class ExtensionGCMAppHandlerTest : public testing::Test { void Register(const std::string& app_id, const std::vector& sender_ids) { - GetGCMProfileService()->Register( + GetGCMDriver()->Register( app_id, sender_ids, base::Bind(&ExtensionGCMAppHandlerTest::RegisterCompleted, @@ -301,12 +298,12 @@ class ExtensionGCMAppHandlerTest : public testing::Test { waiter_.SignalCompleted(); } - gcm::GCMProfileService* GetGCMProfileService() const { - return gcm::GCMProfileServiceFactory::GetForProfile(profile()); + gcm::GCMDriver* GetGCMDriver() const { + return gcm::GCMProfileServiceFactory::GetForProfile(profile())->driver(); } bool HasAppHandlers(const std::string& app_id) const { - return GetGCMProfileService()->app_handlers().count(app_id); + return GetGCMDriver()->app_handlers().count(app_id); } Profile* profile() const { return profile_.get(); } diff --git a/chrome/browser/invalidation/gcm_invalidation_bridge.h b/chrome/browser/invalidation/gcm_invalidation_bridge.h index f020470c8b44bf..e8ad7efd29bec0 100644 --- a/chrome/browser/invalidation/gcm_invalidation_bridge.h +++ b/chrome/browser/invalidation/gcm_invalidation_bridge.h @@ -37,7 +37,7 @@ class GCMInvalidationBridge : public gcm::GCMAppHandler, public: class Core; - GCMInvalidationBridge(gcm::GCMDriver* gcm_service, + GCMInvalidationBridge(gcm::GCMDriver* gcm_driver, IdentityProvider* identity_provider); virtual ~GCMInvalidationBridge(); diff --git a/chrome/browser/invalidation/gcm_invalidation_bridge_unittest.cc b/chrome/browser/invalidation/gcm_invalidation_bridge_unittest.cc index 9b4b6b17207baf..a16ddee4297ee2 100644 --- a/chrome/browser/invalidation/gcm_invalidation_bridge_unittest.cc +++ b/chrome/browser/invalidation/gcm_invalidation_bridge_unittest.cc @@ -4,8 +4,7 @@ #include "base/run_loop.h" #include "chrome/browser/invalidation/gcm_invalidation_bridge.h" -#include "chrome/browser/services/gcm/gcm_profile_service.h" -#include "chrome/browser/services/gcm/gcm_profile_service_factory.h" +#include "chrome/browser/services/gcm/gcm_driver.h" #include "chrome/browser/signin/fake_profile_oauth2_token_service.h" #include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h" #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" @@ -18,17 +17,12 @@ namespace invalidation { namespace { -// Implementation of GCMProfileService::Register that always succeeds with the -// same registrationId. -class FakeGCMProfileService : public gcm::GCMProfileService { +// Implementation of GCMDriver::Register that always succeeds with the same +// registrationId. +class FakeGCMDriver : public gcm::GCMDriver { public: - static KeyedService* Build(content::BrowserContext* context) { - Profile* profile = static_cast(context); - return new FakeGCMProfileService(profile); - } - - explicit FakeGCMProfileService(Profile* profile) - : gcm::GCMProfileService(profile) {} + FakeGCMDriver() {} + virtual ~FakeGCMDriver() {} virtual void Register(const std::string& app_id, const std::vector& sender_ids, @@ -40,7 +34,7 @@ class FakeGCMProfileService : public gcm::GCMProfileService { } private: - DISALLOW_COPY_AND_ASSIGN(FakeGCMProfileService); + DISALLOW_COPY_AND_ASSIGN(FakeGCMDriver); }; class GCMInvalidationBridgeTest : public ::testing::Test { @@ -53,20 +47,16 @@ class GCMInvalidationBridgeTest : public ::testing::Test { TestingProfile::Builder builder; builder.AddTestingFactory(ProfileOAuth2TokenServiceFactory::GetInstance(), &BuildAutoIssuingFakeProfileOAuth2TokenService); - builder.AddTestingFactory(gcm::GCMProfileServiceFactory::GetInstance(), - &FakeGCMProfileService::Build); profile_ = builder.Build(); FakeProfileOAuth2TokenService* token_service = (FakeProfileOAuth2TokenService*) ProfileOAuth2TokenServiceFactory::GetForProfile(profile_.get()); token_service->IssueRefreshTokenForUser("", "fake_refresh_token"); - gcm_profile_service_ = - (FakeGCMProfileService*)gcm::GCMProfileServiceFactory::GetForProfile( - profile_.get()); + gcm_driver_.reset(new FakeGCMDriver()); identity_provider_.reset(new FakeIdentityProvider(token_service)); - bridge_.reset(new GCMInvalidationBridge(gcm_profile_service_, + bridge_.reset(new GCMInvalidationBridge(gcm_driver_.get(), identity_provider_.get())); delegate_ = bridge_->CreateDelegate(); @@ -89,7 +79,7 @@ class GCMInvalidationBridgeTest : public ::testing::Test { content::TestBrowserThreadBundle thread_bundle_; scoped_ptr profile_; - FakeGCMProfileService* gcm_profile_service_; + scoped_ptr gcm_driver_; scoped_ptr identity_provider_; std::vector issued_tokens_; diff --git a/chrome/browser/invalidation/invalidation_service_factory.cc b/chrome/browser/invalidation/invalidation_service_factory.cc index a78014317e32fc..76797b2f571056 100644 --- a/chrome/browser/invalidation/invalidation_service_factory.cc +++ b/chrome/browser/invalidation/invalidation_service_factory.cc @@ -125,7 +125,7 @@ KeyedService* InvalidationServiceFactory::BuildServiceInstanceFor( identity_provider.Pass(), scoped_ptr( new TiclProfileSettingsProvider(profile)), - gcm::GCMProfileServiceFactory::GetForProfile(profile), + gcm::GCMProfileServiceFactory::GetForProfile(profile)->driver(), profile->GetRequestContext()); service->Init(scoped_ptr( new InvalidatorStorage(profile->GetPrefs()))); diff --git a/chrome/browser/invalidation/ticl_invalidation_service.h b/chrome/browser/invalidation/ticl_invalidation_service.h index 07b8e6f102cf88..ebb63a2c4db903 100644 --- a/chrome/browser/invalidation/ticl_invalidation_service.h +++ b/chrome/browser/invalidation/ticl_invalidation_service.h @@ -62,7 +62,7 @@ class TiclInvalidationService : public base::NonThreadSafe, TiclInvalidationService( scoped_ptr identity_provider, scoped_ptr settings_provider, - gcm::GCMDriver* gcm_service, + gcm::GCMDriver* gcm_driver, const scoped_refptr& request_context); virtual ~TiclInvalidationService(); diff --git a/chrome/browser/invalidation/ticl_invalidation_service_unittest.cc b/chrome/browser/invalidation/ticl_invalidation_service_unittest.cc index bd838c5bda478b..92591998cc1eeb 100644 --- a/chrome/browser/invalidation/ticl_invalidation_service_unittest.cc +++ b/chrome/browser/invalidation/ticl_invalidation_service_unittest.cc @@ -37,16 +37,9 @@ class FakeTiclSettingsProvider : public TiclSettingsProvider { class FakeGCMDriver : public gcm::GCMDriver { public: - explicit FakeGCMDriver(OAuth2TokenService* token_service); + FakeGCMDriver(); virtual ~FakeGCMDriver(); - protected: - // gcm::GCMDriver: - virtual bool ShouldStartAutomatically() const OVERRIDE; - virtual base::FilePath GetStorePath() const OVERRIDE; - virtual scoped_refptr - GetURLRequestContextGetter() const OVERRIDE; - private: DISALLOW_COPY_AND_ASSIGN(FakeGCMDriver); }; @@ -61,27 +54,12 @@ bool FakeTiclSettingsProvider::UseGCMChannel() const { return false; } -FakeGCMDriver::FakeGCMDriver(OAuth2TokenService* token_service) - : GCMDriver(scoped_ptr( - new FakeIdentityProvider(token_service))) { +FakeGCMDriver::FakeGCMDriver() { } FakeGCMDriver::~FakeGCMDriver() { } -bool FakeGCMDriver::ShouldStartAutomatically() const { - return false; -} - -base::FilePath FakeGCMDriver::GetStorePath() const { - return base::FilePath(); -} - -scoped_refptr -FakeGCMDriver::GetURLRequestContextGetter() const { - return NULL; -} - } // namespace class TiclInvalidationServiceTestDelegate { @@ -98,11 +76,11 @@ class TiclInvalidationServiceTestDelegate { } void CreateUninitializedInvalidationService() { - gcm_service_.reset(new FakeGCMDriver(&token_service_)); + gcm_driver_.reset(new FakeGCMDriver()); invalidation_service_.reset(new TiclInvalidationService( scoped_ptr(new FakeIdentityProvider(&token_service_)), scoped_ptr(new FakeTiclSettingsProvider), - gcm_service_.get(), + gcm_driver_.get(), NULL)); } @@ -132,7 +110,7 @@ class TiclInvalidationServiceTestDelegate { } FakeOAuth2TokenService token_service_; - scoped_ptr gcm_service_; + scoped_ptr gcm_driver_; syncer::FakeInvalidator* fake_invalidator_; // Owned by the service. scoped_ptr invalidation_service_; diff --git a/chrome/browser/invalidation/ticl_profile_settings_provider_unittest.cc b/chrome/browser/invalidation/ticl_profile_settings_provider_unittest.cc index 179760b8c50c62..d7fb24b74c37c2 100644 --- a/chrome/browser/invalidation/ticl_profile_settings_provider_unittest.cc +++ b/chrome/browser/invalidation/ticl_profile_settings_provider_unittest.cc @@ -56,7 +56,7 @@ void TiclProfileSettingsProviderTest::SetUp() { scoped_ptr(new FakeIdentityProvider(&token_service_)), scoped_ptr( new TiclProfileSettingsProvider(&profile_)), - gcm::GCMProfileServiceFactory::GetForProfile(&profile_), + gcm::GCMProfileServiceFactory::GetForProfile(&profile_)->driver(), profile_.GetRequestContext())); invalidation_service_->Init(scoped_ptr( new syncer::FakeInvalidationStateTracker)); diff --git a/chrome/browser/services/gcm/fake_gcm_profile_service.cc b/chrome/browser/services/gcm/fake_gcm_profile_service.cc index e2b32e63f1063f..b4c7eee6eb986b 100644 --- a/chrome/browser/services/gcm/fake_gcm_profile_service.cc +++ b/chrome/browser/services/gcm/fake_gcm_profile_service.cc @@ -8,38 +8,111 @@ #include "base/message_loop/message_loop.h" #include "base/strings/string_number_conversions.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/services/gcm/fake_gcm_client_factory.h" #include "content/public/browser/browser_context.h" namespace gcm { -// static -KeyedService* FakeGCMProfileService::Build(content::BrowserContext* context) { - Profile* profile = static_cast(context); - return new FakeGCMProfileService(profile); +namespace { + +class FakeGCMDriver : public GCMDriver { + public: + explicit FakeGCMDriver(FakeGCMProfileService* service); + virtual ~FakeGCMDriver(); + + // GCMDriver overrides. + virtual void Shutdown() OVERRIDE; + virtual void AddAppHandler(const std::string& app_id, + GCMAppHandler* handler) OVERRIDE; + virtual void RemoveAppHandler(const std::string& app_id) OVERRIDE; + virtual void Register(const std::string& app_id, + const std::vector& sender_ids, + const RegisterCallback& callback) OVERRIDE; + virtual void Unregister(const std::string& app_id, + const UnregisterCallback& callback) OVERRIDE; + virtual void Send(const std::string& app_id, + const std::string& receiver_id, + const GCMClient::OutgoingMessage& message, + const SendCallback& callback) OVERRIDE; + + private: + FakeGCMProfileService* service_; + + DISALLOW_COPY_AND_ASSIGN(FakeGCMDriver); +}; + +FakeGCMDriver::FakeGCMDriver(FakeGCMProfileService* service) + : service_(service) { } -FakeGCMProfileService::FakeGCMProfileService(Profile* profile) - : GCMProfileService(profile), - collect_(false) {} +FakeGCMDriver::~FakeGCMDriver() { +} -FakeGCMProfileService::~FakeGCMProfileService() {} +void FakeGCMDriver::Shutdown() { +} + +void FakeGCMDriver::AddAppHandler(const std::string& app_id, + GCMAppHandler* handler) { +} -void FakeGCMProfileService::Register(const std::string& app_id, - const std::vector& sender_ids, - const RegisterCallback& callback) { +void FakeGCMDriver::RemoveAppHandler(const std::string& app_id) { +} + +void FakeGCMDriver::Register(const std::string& app_id, + const std::vector& sender_ids, + const RegisterCallback& callback) { base::MessageLoop::current()->PostTask( FROM_HERE, base::Bind(&FakeGCMProfileService::RegisterFinished, - base::Unretained(this), + base::Unretained(service_), app_id, sender_ids, callback)); } +void FakeGCMDriver::Unregister(const std::string& app_id, + const UnregisterCallback& callback) { + base::MessageLoop::current()->PostTask( + FROM_HERE, base::Bind( + &FakeGCMProfileService::UnregisterFinished, + base::Unretained(service_), + app_id, + callback)); +} + +void FakeGCMDriver::Send(const std::string& app_id, + const std::string& receiver_id, + const GCMClient::OutgoingMessage& message, + const SendCallback& callback) { + base::MessageLoop::current()->PostTask( + FROM_HERE, + base::Bind(&FakeGCMProfileService::SendFinished, + base::Unretained(service_), + app_id, + receiver_id, + message, + callback)); +} + +} // namespace + +// static +KeyedService* FakeGCMProfileService::Build(content::BrowserContext* context) { + Profile* profile = static_cast(context); + FakeGCMProfileService* service = new FakeGCMProfileService(profile); + service->SetDriverForTesting(new FakeGCMDriver(service)); + return service; +} + +FakeGCMProfileService::FakeGCMProfileService(Profile* profile) + : collect_(false) {} + +FakeGCMProfileService::~FakeGCMProfileService() {} + void FakeGCMProfileService::RegisterFinished( const std::string& app_id, const std::vector& sender_ids, - const RegisterCallback& callback) { + const GCMDriver::RegisterCallback& callback) { if (collect_) { last_registered_app_id_ = app_id; last_registered_sender_ids_ = sender_ids; @@ -48,31 +121,23 @@ void FakeGCMProfileService::RegisterFinished( callback.Run(base::UintToString(sender_ids.size()), GCMClient::SUCCESS); } -void FakeGCMProfileService::Unregister(const std::string& app_id, - const UnregisterCallback& callback) { - base::MessageLoop::current()->PostTask( - FROM_HERE, base::Bind(callback, GetNextExpectedUnregisterResponse())); -} +void FakeGCMProfileService::UnregisterFinished( + const std::string& app_id, + const GCMDriver::UnregisterCallback& callback) { + GCMClient::Result result = GCMClient::SUCCESS; + if (!unregister_responses_.empty()) { + result = unregister_responses_.front(); + unregister_responses_.pop_front(); + } -void FakeGCMProfileService::Send(const std::string& app_id, - const std::string& receiver_id, - const GCMClient::OutgoingMessage& message, - const SendCallback& callback) { - base::MessageLoop::current()->PostTask( - FROM_HERE, - base::Bind(&FakeGCMProfileService::SendFinished, - base::Unretained(this), - app_id, - receiver_id, - message, - callback)); + callback.Run(result); } void FakeGCMProfileService::SendFinished( const std::string& app_id, const std::string& receiver_id, const GCMClient::OutgoingMessage& message, - const SendCallback& callback) { + const GCMDriver::SendCallback& callback) { if (collect_) { last_sent_message_ = message; last_receiver_id_ = receiver_id; @@ -86,12 +151,4 @@ void FakeGCMProfileService::AddExpectedUnregisterResponse( unregister_responses_.push_back(result); } -GCMClient::Result FakeGCMProfileService::GetNextExpectedUnregisterResponse() { - if (unregister_responses_.empty()) - return GCMClient::SUCCESS; - GCMClient::Result response = *unregister_responses_.begin(); - unregister_responses_.erase(unregister_responses_.begin()); - return response; -} - } // namespace gcm diff --git a/chrome/browser/services/gcm/fake_gcm_profile_service.h b/chrome/browser/services/gcm/fake_gcm_profile_service.h index 119a91e91f1f0f..ee1fe130e40037 100644 --- a/chrome/browser/services/gcm/fake_gcm_profile_service.h +++ b/chrome/browser/services/gcm/fake_gcm_profile_service.h @@ -5,6 +5,10 @@ #ifndef CHROME_BROWSER_SERVICES_GCM_FAKE_GCM_PROFILE_SERVICE_H_ #define CHROME_BROWSER_SERVICES_GCM_FAKE_GCM_PROFILE_SERVICE_H_ +#include +#include + +#include "chrome/browser/services/gcm/gcm_driver.h" #include "chrome/browser/services/gcm/gcm_profile_service.h" namespace content { @@ -23,28 +27,17 @@ class FakeGCMProfileService : public GCMProfileService { explicit FakeGCMProfileService(Profile* profile); virtual ~FakeGCMProfileService(); - // GCMProfileService overrides. - virtual void Register(const std::string& app_id, - const std::vector& sender_ids, - const RegisterCallback& callback) OVERRIDE; - virtual void Unregister(const std::string& app_id, - const UnregisterCallback& callback) OVERRIDE; - virtual void Send(const std::string& app_id, - const std::string& receiver_id, - const GCMClient::OutgoingMessage& message, - const SendCallback& callback) OVERRIDE; - void RegisterFinished(const std::string& app_id, const std::vector& sender_ids, - const RegisterCallback& callback); - + const GCMDriver::RegisterCallback& callback); + void UnregisterFinished(const std::string& app_id, + const GCMDriver::UnregisterCallback& callback); void SendFinished(const std::string& app_id, const std::string& receiver_id, const GCMClient::OutgoingMessage& message, - const SendCallback& callback); + const GCMDriver::SendCallback& callback); void AddExpectedUnregisterResponse(GCMClient::Result result); - GCMClient::Result GetNextExpectedUnregisterResponse(); const GCMClient::OutgoingMessage& last_sent_message() const { return last_sent_message_; @@ -72,7 +65,7 @@ class FakeGCMProfileService : public GCMProfileService { bool collect_; std::string last_registered_app_id_; std::vector last_registered_sender_ids_; - std::vector unregister_responses_; + std::list unregister_responses_; GCMClient::OutgoingMessage last_sent_message_; std::string last_receiver_id_; diff --git a/chrome/browser/services/gcm/gcm_driver.cc b/chrome/browser/services/gcm/gcm_driver.cc index f8bcf72ca257ff..a855a18eeb0906 100644 --- a/chrome/browser/services/gcm/gcm_driver.cc +++ b/chrome/browser/services/gcm/gcm_driver.cc @@ -382,16 +382,15 @@ void GCMDriver::IOWorker::SetGCMRecording(bool recording) { base::Bind(&GCMDriver::GetGCMStatisticsFinished, service_, stats)); } -GCMDriver::GCMDriver(scoped_ptr identity_provider) - : identity_provider_(identity_provider.Pass()), +GCMDriver::GCMDriver( + scoped_ptr gcm_client_factory, + scoped_ptr identity_provider, + const base::FilePath& store_path, + const scoped_refptr& request_context) + : gcm_enabled_(true), gcm_client_ready_(false), + identity_provider_(identity_provider.Pass()), weak_ptr_factory_(this) { -} - -GCMDriver::~GCMDriver() { -} - -void GCMDriver::Initialize(scoped_ptr gcm_client_factory) { // Get the list of available accounts. std::vector account_ids; #if !defined(OS_ANDROID) @@ -400,7 +399,6 @@ void GCMDriver::Initialize(scoped_ptr gcm_client_factory) { // Create and initialize the GCMClient. Note that this does not initiate the // GCM check-in. - DCHECK(!io_worker_); io_worker_.reset(new IOWorker()); content::BrowserThread::PostTask( content::BrowserThread::IO, @@ -408,23 +406,42 @@ void GCMDriver::Initialize(scoped_ptr gcm_client_factory) { base::Bind(&GCMDriver::IOWorker::Initialize, base::Unretained(io_worker_.get()), base::Passed(&gcm_client_factory), - GetStorePath(), + store_path, account_ids, - GetURLRequestContextGetter())); - - // Start the GCM service if the rollout signal indicates yes. - if (ShouldStartAutomatically()) - EnsureStarted(); + request_context)); identity_provider_->AddObserver(this); } -void GCMDriver::Start() { +GCMDriver::GCMDriver() + : gcm_enabled_(true), + gcm_client_ready_(false), + weak_ptr_factory_(this) { +} + +GCMDriver::~GCMDriver() { +} + +void GCMDriver::Enable() { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + if (gcm_enabled_) + return; + gcm_enabled_ = true; + EnsureStarted(); } +void GCMDriver::Disable() { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + + if (!gcm_enabled_) + return; + gcm_enabled_ = false; + + Stop(); +} + void GCMDriver::Stop() { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); @@ -441,7 +458,7 @@ void GCMDriver::Stop() { base::Unretained(io_worker_.get()))); } -void GCMDriver::ShutdownService() { +void GCMDriver::Shutdown() { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); identity_provider_->RemoveObserver(this); for (GCMAppHandlerMap::const_iterator iter = app_handlers_.begin(); @@ -462,6 +479,9 @@ void GCMDriver::AddAppHandler(const std::string& app_id, DCHECK(app_handlers_.find(app_id) == app_handlers_.end()); app_handlers_[app_id] = handler; + + // Ensures that the GCM service is started when there is an interest. + EnsureStarted(); } void GCMDriver::RemoveAppHandler(const std::string& app_id) { @@ -479,7 +499,7 @@ void GCMDriver::Register(const std::string& app_id, DCHECK(!sender_ids.empty()); DCHECK(!callback.is_null()); - GCMClient::Result result = EnsureAppReady(app_id); + GCMClient::Result result = EnsureStarted(); if (result != GCMClient::SUCCESS) { callback.Run(std::string(), result); return; @@ -534,7 +554,7 @@ void GCMDriver::Unregister(const std::string& app_id, DCHECK(!app_id.empty()); DCHECK(!callback.is_null()); - GCMClient::Result result = EnsureAppReady(app_id); + GCMClient::Result result = EnsureStarted(); if (result != GCMClient::SUCCESS) { callback.Run(result); return; @@ -582,7 +602,7 @@ void GCMDriver::Send(const std::string& app_id, DCHECK(!receiver_id.empty()); DCHECK(!callback.is_null()); - GCMClient::Result result = EnsureAppReady(app_id); + GCMClient::Result result = EnsureStarted(); if (result != GCMClient::SUCCESS) { callback.Run(std::string(), result); return; @@ -667,25 +687,29 @@ void GCMDriver::SetGCMRecording(const GetGCMStatisticsCallback& callback, } void GCMDriver::OnActiveAccountLogin() { - if (ShouldStartAutomatically()) - EnsureStarted(); + EnsureStarted(); } void GCMDriver::OnActiveAccountLogout() { CheckOut(); } -void GCMDriver::EnsureStarted() { +GCMClient::Result GCMDriver::EnsureStarted() { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + + if (!gcm_enabled_) + return GCMClient::GCM_DISABLED; + + // Is the user signed in? const std::string account_id = identity_provider_->GetActiveAccountId(); if (account_id.empty()) - return; + return GCMClient::NOT_SIGNED_IN; // CheckIn could be called more than once when: // 1) The password changes. // 2) Register/send function calls it to ensure CheckIn is done. if (account_id_ == account_id) - return; + return GCMClient::SUCCESS; account_id_ = account_id; DCHECK(!delayed_task_controller_); @@ -699,6 +723,8 @@ void GCMDriver::EnsureStarted() { base::Bind(&GCMDriver::IOWorker::Start, base::Unretained(io_worker_.get()), weak_ptr_factory_.GetWeakPtr())); + + return GCMClient::SUCCESS; } void GCMDriver::RemoveCachedData() { @@ -730,19 +756,6 @@ void GCMDriver::CheckOut() { base::Unretained(io_worker_.get()))); } -GCMClient::Result GCMDriver::EnsureAppReady(const std::string& app_id) { - DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); - - // Starts the service if not yet. - EnsureStarted(); - - // If the service cannot be started, bail out. - if (account_id_.empty()) - return GCMClient::NOT_SIGNED_IN; - - return GCMClient::SUCCESS; -} - bool GCMDriver::IsAsyncOperationPending(const std::string& app_id) const { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); return register_callbacks_.find(app_id) != register_callbacks_.end() || @@ -859,4 +872,10 @@ void GCMDriver::GetGCMStatisticsFinished(GCMClient::GCMStatistics stats) { LOG(WARNING) << "request_gcm_statistics_callback_ is NULL."; } +std::string GCMDriver::SignedInUserName() const { + if (IsStarted()) + return identity_provider_->GetActiveUsername(); + return std::string(); +} + } // namespace gcm diff --git a/chrome/browser/services/gcm/gcm_driver.h b/chrome/browser/services/gcm/gcm_driver.h index f0ff169113313e..9db2d66f165fd4 100644 --- a/chrome/browser/services/gcm/gcm_driver.h +++ b/chrome/browser/services/gcm/gcm_driver.h @@ -12,14 +12,16 @@ #include "base/basictypes.h" #include "base/callback.h" #include "base/compiler_specific.h" -#include "base/files/file_path.h" -#include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "components/gcm_driver/default_gcm_app_handler.h" #include "google_apis/gaia/identity_provider.h" #include "google_apis/gcm/gcm_client.h" +namespace base { +class FilePath; +} + namespace extensions { class ExtensionGCMAppHandlerTest; } @@ -45,24 +47,25 @@ class GCMDriver : public IdentityProvider::Observer { typedef base::Callback GetGCMStatisticsCallback; - explicit GCMDriver(scoped_ptr identity_provider); + GCMDriver(scoped_ptr gcm_client_factory, + scoped_ptr identity_provider, + const base::FilePath& store_path, + const scoped_refptr& request_context); virtual ~GCMDriver(); - void Initialize(scoped_ptr gcm_client_factory); - - void Start(); - - void Stop(); + // Enables/disables GCM service. + void Enable(); + void Disable(); // This method must be called before destroying the GCMDriver. Once it has // been called, no other GCMDriver methods may be used. - void ShutdownService(); + virtual void Shutdown(); // Adds a handler for a given app. - void AddAppHandler(const std::string& app_id, GCMAppHandler* handler); + virtual void AddAppHandler(const std::string& app_id, GCMAppHandler* handler); // Remove the handler for a given app. - void RemoveAppHandler(const std::string& app_id); + virtual void RemoveAppHandler(const std::string& app_id); // Registers |sender_id| for an app. A registration ID will be returned by // the GCM server. @@ -110,6 +113,9 @@ class GCMDriver : public IdentityProvider::Observer { void SetGCMRecording(const GetGCMStatisticsCallback& callback, bool recording); + // Returns the user name if the profile is signed in. Empty string otherwise. + std::string SignedInUserName() const; + // IdentityProvider::Observer: virtual void OnActiveAccountLogin() OVERRIDE; virtual void OnActiveAccountLogout() OVERRIDE; @@ -117,22 +123,21 @@ class GCMDriver : public IdentityProvider::Observer { const GCMAppHandlerMap& app_handlers() const { return app_handlers_; } protected: - virtual bool ShouldStartAutomatically() const = 0; - - virtual base::FilePath GetStorePath() const = 0; - - virtual scoped_refptr - GetURLRequestContextGetter() const = 0; - - scoped_ptr identity_provider_; + // Used for constructing fake GCMDriver for testing purpose. + GCMDriver(); private: class DelayedTaskController; class IOWorker; - // Ensures that the GCMClient is started and the GCM check-in is done if the - // |identity_provider_| is able to supply an account ID. - void EnsureStarted(); + // Ensures that the GCM service starts when all of the following conditions + // satisfy: + // 1) GCM is enabled. + // 2) The identity provider is able to supply an account ID. + GCMClient::Result EnsureStarted(); + + // Stops the GCM service. It can be restarted by calling EnsureStarted again. + void Stop(); // Remove cached data when GCM service is stopped. void RemoveCachedData(); @@ -140,9 +145,6 @@ class GCMDriver : public IdentityProvider::Observer { // Checks out of GCM and erases any cached and persisted data. void CheckOut(); - // Ensures that the app is ready for GCM functions and events. - GCMClient::Result EnsureAppReady(const std::string& app_id); - // Should be called when an app with |app_id| is trying to un/register. // Checks whether another un/registration is in progress. bool IsAsyncOperationPending(const std::string& app_id) const; @@ -174,6 +176,9 @@ class GCMDriver : public IdentityProvider::Observer { void GetGCMStatisticsFinished(GCMClient::GCMStatistics stats); + // Flag to indicate if GCM is enabled. + bool gcm_enabled_; + // Flag to indicate if GCMClient is ready. bool gcm_client_ready_; @@ -181,6 +186,8 @@ class GCMDriver : public IdentityProvider::Observer { // is not running. std::string account_id_; + scoped_ptr identity_provider_; + scoped_ptr delayed_task_controller_; // For all the work occurring on the IO thread. Must be destroyed on the IO diff --git a/chrome/browser/services/gcm/gcm_driver_unittest.cc b/chrome/browser/services/gcm/gcm_driver_unittest.cc index 3d220797532e81..11705131c6b8b9 100644 --- a/chrome/browser/services/gcm/gcm_driver_unittest.cc +++ b/chrome/browser/services/gcm/gcm_driver_unittest.cc @@ -101,29 +101,6 @@ class FakeGCMAppHandler : public GCMAppHandler { DISALLOW_COPY_AND_ASSIGN(FakeGCMAppHandler); }; -class TestGCMDriver : public GCMDriver { - public: - TestGCMDriver( - bool start_automatically, - scoped_ptr identity_provider, - const scoped_refptr& request_context); - virtual ~TestGCMDriver(); - - protected: - // GCMDriver: - virtual bool ShouldStartAutomatically() const OVERRIDE; - virtual base::FilePath GetStorePath() const OVERRIDE; - virtual scoped_refptr - GetURLRequestContextGetter() const OVERRIDE; - - private: - base::ScopedTempDir temp_dir_; - scoped_refptr request_context_; - const bool start_automatically_; - - DISALLOW_COPY_AND_ASSIGN(TestGCMDriver); -}; - FakeGCMAppHandler::FakeGCMAppHandler() : received_event_(NO_EVENT) { } @@ -175,33 +152,6 @@ void FakeGCMAppHandler::ClearResults() { send_error_details_ = GCMClient::SendErrorDetails(); } -TestGCMDriver::TestGCMDriver( - bool start_automatically, - scoped_ptr identity_provider, - const scoped_refptr& request_context) - : GCMDriver(identity_provider.Pass()), - request_context_(request_context), - start_automatically_(start_automatically) { - if (!temp_dir_.CreateUniqueTempDir()) - ADD_FAILURE(); -} - -TestGCMDriver::~TestGCMDriver() { -} - -bool TestGCMDriver::ShouldStartAutomatically() const { - return start_automatically_; -} - -base::FilePath TestGCMDriver::GetStorePath() const { - return temp_dir_.path(); -} - -scoped_refptr -TestGCMDriver::GetURLRequestContextGetter() const { - return request_context_; -} - } // namespace class GCMDriverTest : public testing::Test { @@ -218,7 +168,7 @@ class GCMDriverTest : public testing::Test { virtual void SetUp() OVERRIDE; virtual void TearDown() OVERRIDE; - TestGCMDriver* driver() { return driver_.get(); } + GCMDriver* driver() { return driver_.get(); } FakeGCMAppHandler* gcm_app_handler() { return gcm_app_handler_.get(); } const std::string& registration_id() const { return registration_id_; } GCMClient::Result registration_result() const { return registration_result_; } @@ -228,14 +178,12 @@ class GCMDriverTest : public testing::Test { return unregistration_result_; } - void ClearRegistrationResult(); - void ClearUnregistrationResult(); + void ClearResults(); bool HasAppHandlers() const; FakeGCMClient* GetGCMClient(); - void CreateDriver(bool start_automatically, - FakeGCMClient::StartMode gcm_client_start_mode); + void CreateDriver(FakeGCMClient::StartMode gcm_client_start_mode); void SignIn(const std::string& account_id); void SignOut(); @@ -258,10 +206,11 @@ class GCMDriverTest : public testing::Test { void UnregisterCompleted(GCMClient::Result result); scoped_ptr thread_bundle_; + base::ScopedTempDir temp_dir_; FakeOAuth2TokenService token_service_; scoped_ptr identity_provider_owner_; FakeIdentityProvider* identity_provider_; - scoped_ptr driver_; + scoped_ptr driver_; scoped_ptr gcm_app_handler_; base::Closure async_operation_completed_callback_; @@ -290,23 +239,25 @@ GCMDriverTest::~GCMDriverTest() { void GCMDriverTest::SetUp() { thread_bundle_.reset(new content::TestBrowserThreadBundle( content::TestBrowserThreadBundle::REAL_IO_THREAD)); + ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); } void GCMDriverTest::TearDown() { if (!driver_) return; - driver_->ShutdownService(); + driver_->Shutdown(); driver_.reset(); PumpIOLoop(); } -void GCMDriverTest::ClearRegistrationResult() { +void GCMDriverTest::ClearResults() { registration_id_.clear(); registration_result_ = GCMClient::UNKNOWN_ERROR; -} -void GCMDriverTest::ClearUnregistrationResult() { + send_message_id_.clear(); + send_result_ = GCMClient::UNKNOWN_ERROR; + unregistration_result_ = GCMClient::UNKNOWN_ERROR; } @@ -319,18 +270,17 @@ FakeGCMClient* GCMDriverTest::GetGCMClient() { } void GCMDriverTest::CreateDriver( - bool start_automatically, FakeGCMClient::StartMode gcm_client_start_mode) { scoped_refptr request_context = new net::TestURLRequestContextGetter( content::BrowserThread::GetMessageLoopProxyForThread( content::BrowserThread::IO)); - driver_.reset(new TestGCMDriver( - start_automatically, + driver_.reset(new GCMDriver( + scoped_ptr(new FakeGCMClientFactory( + gcm_client_start_mode)).Pass(), identity_provider_owner_.PassAs(), + temp_dir_.path(), request_context)); - driver_->Initialize(scoped_ptr( - new FakeGCMClientFactory(gcm_client_start_mode))); gcm_app_handler_.reset(new FakeGCMAppHandler); driver_->AddAppHandler(kTestAppID1, gcm_app_handler_.get()); @@ -419,7 +369,7 @@ void GCMDriverTest::UnregisterCompleted(GCMClient::Result result) { TEST_F(GCMDriverTest, CreateGCMDriverBeforeSignIn) { // Create CreateGMCService first. - CreateDriver(true, FakeGCMClient::NO_DELAY_START); + CreateDriver(FakeGCMClient::NO_DELAY_START); EXPECT_FALSE(driver()->IsStarted()); // Sign in. This will kick off the check-in. @@ -432,20 +382,20 @@ TEST_F(GCMDriverTest, CreateGCMDriverAfterSignIn) { SignIn(kTestAccountID1); // Create GCMeService after sign-in. - CreateDriver(true, FakeGCMClient::NO_DELAY_START); + CreateDriver(FakeGCMClient::NO_DELAY_START); EXPECT_TRUE(driver()->IsStarted()); } TEST_F(GCMDriverTest, Shutdown) { - CreateDriver(true, FakeGCMClient::NO_DELAY_START); + CreateDriver(FakeGCMClient::NO_DELAY_START); EXPECT_TRUE(HasAppHandlers()); - driver()->ShutdownService(); + driver()->Shutdown(); EXPECT_FALSE(HasAppHandlers()); } TEST_F(GCMDriverTest, SignInAndSignOutUnderPositiveChannelSignal) { - CreateDriver(true, FakeGCMClient::NO_DELAY_START); + CreateDriver(FakeGCMClient::NO_DELAY_START); SignIn(kTestAccountID1); // GCMClient should be loaded. @@ -459,25 +409,8 @@ TEST_F(GCMDriverTest, SignInAndSignOutUnderPositiveChannelSignal) { EXPECT_EQ(FakeGCMClient::CHECKED_OUT, GetGCMClient()->status()); } -TEST_F(GCMDriverTest, SignInAndSignOutUnderNonPositiveChannelSignal) { - // Non-positive channel signal will prevent GCMClient from checking in during - // sign-in. - CreateDriver(false, FakeGCMClient::NO_DELAY_START); - SignIn(kTestAccountID1); - - // GCMClient should not be loaded. - EXPECT_FALSE(driver()->IsGCMClientReady()); - EXPECT_EQ(FakeGCMClient::UNINITIALIZED, GetGCMClient()->status()); - - SignOut(); - - // Check-out should still be performed. - EXPECT_FALSE(driver()->IsGCMClientReady()); - EXPECT_EQ(FakeGCMClient::CHECKED_OUT, GetGCMClient()->status()); -} - TEST_F(GCMDriverTest, SignOutAndThenSignIn) { - CreateDriver(true, FakeGCMClient::NO_DELAY_START); + CreateDriver(FakeGCMClient::NO_DELAY_START); SignIn(kTestAccountID1); // GCMClient should be loaded. @@ -498,16 +431,16 @@ TEST_F(GCMDriverTest, SignOutAndThenSignIn) { EXPECT_EQ(FakeGCMClient::STARTED, GetGCMClient()->status()); } -TEST_F(GCMDriverTest, StopAndRestartGCM) { - CreateDriver(true, FakeGCMClient::NO_DELAY_START); +TEST_F(GCMDriverTest, DisableAndReenableGCM) { + CreateDriver(FakeGCMClient::NO_DELAY_START); SignIn(kTestAccountID1); - // GCMClient should be loaded. + // GCMClient should be started. EXPECT_TRUE(driver()->IsGCMClientReady()); EXPECT_EQ(FakeGCMClient::STARTED, GetGCMClient()->status()); - // Stops the GCM. - driver()->Stop(); + // Disables the GCM. + driver()->Disable(); PumpIOLoop(); PumpUILoop(); @@ -515,17 +448,17 @@ TEST_F(GCMDriverTest, StopAndRestartGCM) { EXPECT_FALSE(driver()->IsGCMClientReady()); EXPECT_EQ(FakeGCMClient::STOPPED, GetGCMClient()->status()); - // Restarts the GCM. - driver()->Start(); + // Enables the GCM. + driver()->Enable(); PumpIOLoop(); PumpUILoop(); - // GCMClient should be loaded. + // GCMClient should be started. EXPECT_TRUE(driver()->IsGCMClientReady()); EXPECT_EQ(FakeGCMClient::STARTED, GetGCMClient()->status()); - // Stops the GCM. - driver()->Stop(); + // Disables the GCM. + driver()->Disable(); PumpIOLoop(); PumpUILoop(); @@ -541,83 +474,68 @@ TEST_F(GCMDriverTest, StopAndRestartGCM) { EXPECT_EQ(FakeGCMClient::CHECKED_OUT, GetGCMClient()->status()); } -TEST_F(GCMDriverTest, RegisterWhenNotSignedIn) { - CreateDriver(true, FakeGCMClient::NO_DELAY_START); - +TEST_F(GCMDriverTest, RegisterFailed) { std::vector sender_ids; sender_ids.push_back("sender1"); + + CreateDriver(FakeGCMClient::NO_DELAY_START); + + // Registration fails when GCM is disabled. + driver()->Disable(); Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT); + EXPECT_TRUE(registration_id().empty()); + EXPECT_EQ(GCMClient::GCM_DISABLED, registration_result()); + ClearResults(); + + // Registration fails when the sign-in does not occur. + driver()->Enable(); + Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT); EXPECT_TRUE(registration_id().empty()); EXPECT_EQ(GCMClient::NOT_SIGNED_IN, registration_result()); } -TEST_F(GCMDriverTest, RegisterUnderNonPositiveChannelSignal) { - // Non-positive channel signal will prevent GCMClient from checking in during - // sign-in. - CreateDriver(false, FakeGCMClient::NO_DELAY_START); - SignIn(kTestAccountID1); - - // GCMClient should not be checked in. - EXPECT_FALSE(driver()->IsGCMClientReady()); - EXPECT_EQ(FakeGCMClient::UNINITIALIZED, GetGCMClient()->status()); +TEST_F(GCMDriverTest, UnregisterFailed) { + CreateDriver(FakeGCMClient::NO_DELAY_START); - // Invoking register will make GCMClient checked in. - std::vector sender_ids; - sender_ids.push_back("sender1"); - Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT); + // Unregistration fails when GCM is disabled. + driver()->Disable(); + Unregister(kTestAppID1, GCMDriverTest::WAIT); + EXPECT_EQ(GCMClient::GCM_DISABLED, unregistration_result()); - // GCMClient should be checked in. - EXPECT_TRUE(driver()->IsGCMClientReady()); - EXPECT_EQ(FakeGCMClient::STARTED, GetGCMClient()->status()); + ClearResults(); - // Registration should succeed. - const std::string expected_registration_id = - FakeGCMClient::GetRegistrationIdFromSenderIds(sender_ids); - EXPECT_EQ(expected_registration_id, registration_id()); - EXPECT_EQ(GCMClient::SUCCESS, registration_result()); + // Unregistration fails when the sign-in does not occur. + driver()->Enable(); + Unregister(kTestAppID1, GCMDriverTest::WAIT); + EXPECT_EQ(GCMClient::NOT_SIGNED_IN, unregistration_result()); } -TEST_F(GCMDriverTest, SendWhenNotSignedIn) { - CreateDriver(true, FakeGCMClient::NO_DELAY_START); - +TEST_F(GCMDriverTest, SendFailed) { GCMClient::OutgoingMessage message; message.id = "1"; message.data["key1"] = "value1"; - Send(kTestAppID1, kUserID1, message, GCMDriverTest::WAIT); - EXPECT_TRUE(send_message_id().empty()); - EXPECT_EQ(GCMClient::NOT_SIGNED_IN, send_result()); -} + CreateDriver(FakeGCMClient::NO_DELAY_START); -TEST_F(GCMDriverTest, SendUnderNonPositiveChannelSignal) { - // Non-positive channel signal will prevent GCMClient from checking in during - // sign-in. - CreateDriver(false, FakeGCMClient::NO_DELAY_START); - SignIn(kTestAccountID1); - - // GCMClient should not be checked in. - EXPECT_FALSE(driver()->IsGCMClientReady()); - EXPECT_EQ(FakeGCMClient::UNINITIALIZED, GetGCMClient()->status()); - - // Invoking send will make GCMClient checked in. - GCMClient::OutgoingMessage message; - message.id = "1"; - message.data["key1"] = "value1"; + // Sending fails when GCM is disabled. + driver()->Disable(); Send(kTestAppID1, kUserID1, message, GCMDriverTest::WAIT); + EXPECT_TRUE(send_message_id().empty()); + EXPECT_EQ(GCMClient::GCM_DISABLED, send_result()); - // GCMClient should be checked in. - EXPECT_TRUE(driver()->IsGCMClientReady()); - EXPECT_EQ(FakeGCMClient::STARTED, GetGCMClient()->status()); + ClearResults(); - // Sending should succeed. - EXPECT_EQ(message.id, send_message_id()); - EXPECT_EQ(GCMClient::SUCCESS, send_result()); + // Registration fails when the sign-in does not occur. + driver()->Enable(); + Send(kTestAppID1, kUserID1, message, GCMDriverTest::WAIT); + EXPECT_TRUE(send_message_id().empty()); + EXPECT_EQ(GCMClient::NOT_SIGNED_IN, send_result()); } TEST_F(GCMDriverTest, GCMClientNotReadyBeforeRegistration) { // Make GCMClient not ready initially. - CreateDriver(true, FakeGCMClient::DELAY_START); + CreateDriver(FakeGCMClient::DELAY_START); SignIn(kTestAccountID1); // The registration is on hold until GCMClient is ready. @@ -640,7 +558,7 @@ TEST_F(GCMDriverTest, GCMClientNotReadyBeforeRegistration) { TEST_F(GCMDriverTest, GCMClientNotReadyBeforeSending) { // Make GCMClient not ready initially. - CreateDriver(true, FakeGCMClient::DELAY_START); + CreateDriver(FakeGCMClient::DELAY_START); SignIn(kTestAccountID1); // The sending is on hold until GCMClient is ready. @@ -684,7 +602,7 @@ GCMDriverFunctionalTest::~GCMDriverFunctionalTest() { void GCMDriverFunctionalTest::SetUp() { GCMDriverTest::SetUp(); - CreateDriver(true, FakeGCMClient::NO_DELAY_START); + CreateDriver(FakeGCMClient::NO_DELAY_START); SignIn(kTestAccountID1); } @@ -721,7 +639,7 @@ TEST_F(GCMDriverFunctionalTest, RegisterAgainWithSameSenderIDs) { // Clears the results the would be set by the Register callback in preparation // to call register 2nd time. - ClearRegistrationResult(); + ClearResults(); // Calling register 2nd time with the same set of sender IDs but different // ordering will get back the same registration ID. @@ -808,7 +726,7 @@ TEST_F(GCMDriverFunctionalTest, UnregisterWhenAsyncOperationPending) { Unregister(kTestAppID1, GCMDriverTest::WAIT); EXPECT_EQ(GCMClient::ASYNC_OPERATION_PENDING, unregistration_result()); - ClearUnregistrationResult(); + ClearResults(); // Complete unregistration. WaitForAsyncOperation(); @@ -828,7 +746,7 @@ TEST_F(GCMDriverFunctionalTest, RegisterWhenAsyncOperationPending) { Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT); EXPECT_EQ(GCMClient::ASYNC_OPERATION_PENDING, registration_result()); - ClearRegistrationResult(); + ClearResults(); // Complete the registration. WaitForAsyncOperation(); diff --git a/chrome/browser/services/gcm/gcm_profile_service.cc b/chrome/browser/services/gcm/gcm_profile_service.cc index a14ae00d55bc6f..39283d9f31fbc0 100644 --- a/chrome/browser/services/gcm/gcm_profile_service.cc +++ b/chrome/browser/services/gcm/gcm_profile_service.cc @@ -9,12 +9,14 @@ #include "base/prefs/pref_service.h" #include "base/values.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/services/gcm/gcm_driver.h" #include "chrome/browser/signin/profile_identity_provider.h" #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_version_info.h" #include "chrome/common/pref_names.h" +#include "components/gcm_driver/gcm_client_factory.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/signin/core/browser/signin_manager.h" #include "google_apis/gaia/identity_provider.h" @@ -73,43 +75,61 @@ void GCMProfileService::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); } -GCMProfileService::GCMProfileService(Profile* profile) - : GCMDriver(scoped_ptr(new ProfileIdentityProvider( - SigninManagerFactory::GetForProfile(profile), - ProfileOAuth2TokenServiceFactory::GetForProfile(profile), +GCMProfileService::GCMProfileService( + Profile* profile, + scoped_ptr gcm_client_factory) + : profile_(profile) { + DCHECK(!profile->IsOffTheRecord()); + #if defined(OS_ANDROID) - NULL))), + LoginUIService* login_ui_service = NULL; #else - LoginUIServiceFactory::GetForProfile(profile)))), + LoginUIService* login_ui_service = + LoginUIServiceFactory::GetForProfile(profile_); #endif - profile_(profile) { - DCHECK(!profile->IsOffTheRecord()); + driver_.reset(new GCMDriver( + gcm_client_factory.Pass(), + scoped_ptr(new ProfileIdentityProvider( + SigninManagerFactory::GetForProfile(profile_), + ProfileOAuth2TokenServiceFactory::GetForProfile(profile_), + login_ui_service)), + profile_->GetPath().Append(chrome::kGCMStoreDirname), + profile_->GetRequestContext())); +} + +GCMProfileService::GCMProfileService() : profile_(NULL) { } GCMProfileService::~GCMProfileService() { } -void GCMProfileService::Shutdown() { - ShutdownService(); +void GCMProfileService::AddAppHandler(const std::string& app_id, + GCMAppHandler* handler) { + if (driver_) + driver_->AddAppHandler(app_id, handler); } -std::string GCMProfileService::SignedInUserName() const { - if (IsStarted()) - return identity_provider_->GetActiveUsername(); - return std::string(); +void GCMProfileService::RemoveAppHandler(const std::string& app_id) { + if (driver_) + driver_->RemoveAppHandler(app_id); } -bool GCMProfileService::ShouldStartAutomatically() const { - return GetGCMEnabledState(profile_) == ALWAYS_ENABLED; +void GCMProfileService::Register(const std::string& app_id, + const std::vector& sender_ids, + const GCMDriver::RegisterCallback& callback) { + if (driver_) + driver_->Register(app_id, sender_ids, callback); } -base::FilePath GCMProfileService::GetStorePath() const { - return profile_->GetPath().Append(chrome::kGCMStoreDirname); +void GCMProfileService::Shutdown() { + if (driver_) { + driver_->Shutdown(); + driver_.reset(); + } } -scoped_refptr -GCMProfileService::GetURLRequestContextGetter() const { - return profile_->GetRequestContext(); +void GCMProfileService::SetDriverForTesting(GCMDriver* driver) { + driver_.reset(driver); } } // namespace gcm diff --git a/chrome/browser/services/gcm/gcm_profile_service.h b/chrome/browser/services/gcm/gcm_profile_service.h index 69f346f007455b..d68c65dc3c399c 100644 --- a/chrome/browser/services/gcm/gcm_profile_service.h +++ b/chrome/browser/services/gcm/gcm_profile_service.h @@ -10,6 +10,8 @@ #include "base/compiler_specific.h" #include "base/macros.h" #include "base/memory/scoped_ptr.h" +// TODO(jianli): include needed for obsolete methods that are going to be +// removed soon. #include "chrome/browser/services/gcm/gcm_driver.h" #include "components/keyed_service/core/keyed_service.h" @@ -21,8 +23,11 @@ class PrefRegistrySyncable; namespace gcm { -// A specialization of GCMDriver that is tied to a Profile. -class GCMProfileService : public GCMDriver, public KeyedService { +class GCMClientFactory; +class GCMDriver; + +// Providing GCM service, via GCMDriver, to a profile. +class GCMProfileService : public KeyedService { public: // Any change made to this enum should have corresponding change in the // GetGCMEnabledStateString(...) function. @@ -45,26 +50,35 @@ class GCMProfileService : public GCMDriver, public KeyedService { // Register profile-specific prefs for GCM. static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); - explicit GCMProfileService(Profile* profile); + GCMProfileService(Profile* profile, + scoped_ptr gcm_client_factory); virtual ~GCMProfileService(); + // TODO(jianli): obsolete methods that are going to be removed soon. + void AddAppHandler(const std::string& app_id, GCMAppHandler* handler); + void RemoveAppHandler(const std::string& app_id); + void Register(const std::string& app_id, + const std::vector& sender_ids, + const GCMDriver::RegisterCallback& callback); + // KeyedService: virtual void Shutdown() OVERRIDE; - // Returns the user name if the profile is signed in. - std::string SignedInUserName() const; + // For testing purpose. + void SetDriverForTesting(GCMDriver* driver); + + GCMDriver* driver() const { return driver_.get(); } protected: - // Overridden from GCMDriver: - virtual bool ShouldStartAutomatically() const OVERRIDE; - virtual base::FilePath GetStorePath() const OVERRIDE; - virtual scoped_refptr - GetURLRequestContextGetter() const OVERRIDE; + // Used for constructing fake GCMProfileService for testing purpose. + GCMProfileService(); private: // The profile which owns this object. Profile* profile_; + scoped_ptr driver_; + DISALLOW_COPY_AND_ASSIGN(GCMProfileService); }; diff --git a/chrome/browser/services/gcm/gcm_profile_service_factory.cc b/chrome/browser/services/gcm/gcm_profile_service_factory.cc index 2e380b1579c454..2cd5bd723ca605 100644 --- a/chrome/browser/services/gcm/gcm_profile_service_factory.cc +++ b/chrome/browser/services/gcm/gcm_profile_service_factory.cc @@ -50,11 +50,9 @@ GCMProfileServiceFactory::~GCMProfileServiceFactory() { KeyedService* GCMProfileServiceFactory::BuildServiceInstanceFor( content::BrowserContext* context) const { - Profile* profile = static_cast(context); - GCMProfileService* service = new GCMProfileService(profile); - scoped_ptr gcm_client_factory(new GCMClientFactory); - service->Initialize(gcm_client_factory.Pass()); - return service; + return new GCMProfileService( + Profile::FromBrowserContext(context), + scoped_ptr(new GCMClientFactory)); } content::BrowserContext* GCMProfileServiceFactory::GetBrowserContextToUse( diff --git a/chrome/browser/services/gcm/gcm_profile_service_unittest.cc b/chrome/browser/services/gcm/gcm_profile_service_unittest.cc index 1fe24c32ac123b..ff6ce35ad46df5 100644 --- a/chrome/browser/services/gcm/gcm_profile_service_unittest.cc +++ b/chrome/browser/services/gcm/gcm_profile_service_unittest.cc @@ -14,6 +14,7 @@ #include "chrome/browser/services/gcm/fake_gcm_client.h" #include "chrome/browser/services/gcm/fake_gcm_client_factory.h" #include "chrome/browser/services/gcm/fake_signin_manager.h" +#include "chrome/browser/services/gcm/gcm_driver.h" #include "chrome/browser/services/gcm/gcm_profile_service_factory.h" #include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/test/base/testing_profile.h" @@ -33,7 +34,10 @@ const char kTestAppID[] = "TestApp"; const char kUserID[] = "user"; KeyedService* BuildGCMProfileService(content::BrowserContext* context) { - return new GCMProfileService(Profile::FromBrowserContext(context)); + return new GCMProfileService( + Profile::FromBrowserContext(context), + scoped_ptr( + new FakeGCMClientFactory(FakeGCMClient::NO_DELAY_START))); } } // namespace @@ -49,25 +53,38 @@ class GCMProfileServiceTest : public testing::Test { FakeGCMClient* GetGCMClient() const; void RegisterAndWaitForCompletion(const std::vector& sender_ids); + void UnregisterAndWaitForCompletion(); void SendAndWaitForCompletion(const GCMClient::OutgoingMessage& message); void RegisterCompleted(const base::Closure& callback, const std::string& registration_id, GCMClient::Result result); + void UnregisterCompleted(const base::Closure& callback, + GCMClient::Result result); void SendCompleted(const base::Closure& callback, const std::string& message_id, GCMClient::Result result); + GCMDriver* driver() const { return gcm_profile_service_->driver(); } + std::string registration_id() const { return registration_id_; } + GCMClient::Result registration_result() const { return registration_result_; } + GCMClient::Result unregistration_result() const { + return unregistration_result_; + } + std::string send_message_id() const { return send_message_id_; } + GCMClient::Result send_result() const { return send_result_; } + + private: content::TestBrowserThreadBundle thread_bundle_; scoped_ptr profile_; GCMProfileService* gcm_profile_service_; std::string registration_id_; GCMClient::Result registration_result_; + GCMClient::Result unregistration_result_; std::string send_message_id_; GCMClient::Result send_result_; - private: DISALLOW_COPY_AND_ASSIGN(GCMProfileServiceTest); }; @@ -82,7 +99,7 @@ GCMProfileServiceTest::~GCMProfileServiceTest() { FakeGCMClient* GCMProfileServiceTest::GetGCMClient() const { return static_cast( - gcm_profile_service_->GetGCMClientForTesting()); + gcm_profile_service_->driver()->GetGCMClientForTesting()); } void GCMProfileServiceTest::SetUp() { @@ -95,8 +112,6 @@ void GCMProfileServiceTest::SetUp() { GCMProfileServiceFactory::GetInstance()->SetTestingFactoryAndUse( profile_.get(), &BuildGCMProfileService)); - gcm_profile_service_->Initialize(scoped_ptr( - new FakeGCMClientFactory(FakeGCMClient::NO_DELAY_START))); FakeSigninManager* signin_manager = static_cast( SigninManagerFactory::GetInstance()->GetForProfile(profile_.get())); @@ -107,7 +122,7 @@ void GCMProfileServiceTest::SetUp() { void GCMProfileServiceTest::RegisterAndWaitForCompletion( const std::vector& sender_ids) { base::RunLoop run_loop; - gcm_profile_service_->Register( + gcm_profile_service_->driver()->Register( kTestAppID, sender_ids, base::Bind(&GCMProfileServiceTest::RegisterCompleted, @@ -116,15 +131,26 @@ void GCMProfileServiceTest::RegisterAndWaitForCompletion( run_loop.Run(); } +void GCMProfileServiceTest::UnregisterAndWaitForCompletion() { + base::RunLoop run_loop; + gcm_profile_service_->driver()->Unregister( + kTestAppID, + base::Bind(&GCMProfileServiceTest::UnregisterCompleted, + base::Unretained(this), + run_loop.QuitClosure())); + run_loop.Run(); +} + void GCMProfileServiceTest::SendAndWaitForCompletion( const GCMClient::OutgoingMessage& message) { base::RunLoop run_loop; - gcm_profile_service_->Send(kTestAppID, - kUserID, - message, - base::Bind(&GCMProfileServiceTest::SendCompleted, - base::Unretained(this), - run_loop.QuitClosure())); + gcm_profile_service_->driver()->Send( + kTestAppID, + kUserID, + message, + base::Bind(&GCMProfileServiceTest::SendCompleted, + base::Unretained(this), + run_loop.QuitClosure())); run_loop.Run(); } @@ -137,6 +163,13 @@ void GCMProfileServiceTest::RegisterCompleted( callback.Run(); } +void GCMProfileServiceTest::UnregisterCompleted( + const base::Closure& callback, + GCMClient::Result result) { + unregistration_result_ = result; + callback.Run(); +} + void GCMProfileServiceTest::SendCompleted( const base::Closure& callback, const std::string& message_id, @@ -146,45 +179,28 @@ void GCMProfileServiceTest::SendCompleted( callback.Run(); } -TEST_F(GCMProfileServiceTest, RegisterUnderNeutralChannelSignal) { - // GCMClient should not be checked in. - EXPECT_FALSE(gcm_profile_service_->IsGCMClientReady()); - EXPECT_EQ(FakeGCMClient::UNINITIALIZED, GetGCMClient()->status()); - - // Invoking register will make GCMClient checked in. +TEST_F(GCMProfileServiceTest, RegisterAndUnregister) { std::vector sender_ids; sender_ids.push_back("sender"); RegisterAndWaitForCompletion(sender_ids); - // GCMClient should be checked in. - EXPECT_TRUE(gcm_profile_service_->IsGCMClientReady()); - EXPECT_EQ(FakeGCMClient::STARTED, GetGCMClient()->status()); - - // Registration should succeed. std::string expected_registration_id = FakeGCMClient::GetRegistrationIdFromSenderIds(sender_ids); - EXPECT_EQ(expected_registration_id, registration_id_); - EXPECT_EQ(GCMClient::SUCCESS, registration_result_); -} + EXPECT_EQ(expected_registration_id, registration_id()); + EXPECT_EQ(GCMClient::SUCCESS, registration_result()); -TEST_F(GCMProfileServiceTest, SendUnderNeutralChannelSignal) { - // GCMClient should not be checked in. - EXPECT_FALSE(gcm_profile_service_->IsGCMClientReady()); - EXPECT_EQ(FakeGCMClient::UNINITIALIZED, GetGCMClient()->status()); + UnregisterAndWaitForCompletion(); + EXPECT_EQ(GCMClient::SUCCESS, unregistration_result()); +} - // Invoking send will make GCMClient checked in. +TEST_F(GCMProfileServiceTest, Send) { GCMClient::OutgoingMessage message; message.id = "1"; message.data["key1"] = "value1"; SendAndWaitForCompletion( message); - // GCMClient should be checked in. - EXPECT_TRUE(gcm_profile_service_->IsGCMClientReady()); - EXPECT_EQ(FakeGCMClient::STARTED, GetGCMClient()->status()); - - // Sending should succeed. - EXPECT_EQ(message.id, send_message_id_); - EXPECT_EQ(GCMClient::SUCCESS, send_result_); + EXPECT_EQ(message.id, send_message_id()); + EXPECT_EQ(GCMClient::SUCCESS, send_result()); } } // namespace gcm diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc index 627a732ba9bdc1..58e87f3d8f0799 100644 --- a/chrome/browser/sync/profile_sync_service.cc +++ b/chrome/browser/sync/profile_sync_service.cc @@ -30,6 +30,7 @@ #include "chrome/browser/net/chrome_cookie_notification_details.h" #include "chrome/browser/prefs/pref_service_syncable.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/services/gcm/gcm_driver.h" #include "chrome/browser/services/gcm/gcm_profile_service.h" #include "chrome/browser/services/gcm/gcm_profile_service_factory.h" #include "chrome/browser/signin/about_signin_internals_factory.h" @@ -1023,11 +1024,11 @@ void ProfileSyncService::OnExperimentsChanged( syncer::Experiments::ENABLED); gcm::GCMProfileService* gcm_profile_service = gcm::GCMProfileServiceFactory::GetForProfile(profile()); - if (gcm_profile_service) { + if (gcm_profile_service && gcm_profile_service->driver()) { if (experiments.gcm_channel_state == syncer::Experiments::SUPPRESSED) - gcm_profile_service->Stop(); + gcm_profile_service->driver()->Disable(); else - gcm_profile_service->Start(); + gcm_profile_service->driver()->Enable(); } } else { profile()->GetPrefs()->ClearPref(prefs::kGCMChannelEnabled); diff --git a/chrome/browser/ui/webui/gcm_internals_ui.cc b/chrome/browser/ui/webui/gcm_internals_ui.cc index bc560a8a157028..7f63accb06ae0a 100644 --- a/chrome/browser/ui/webui/gcm_internals_ui.cc +++ b/chrome/browser/ui/webui/gcm_internals_ui.cc @@ -14,6 +14,7 @@ #include "base/strings/stringprintf.h" #include "base/values.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/services/gcm/gcm_driver.h" #include "chrome/browser/services/gcm/gcm_profile_service.h" #include "chrome/browser/services/gcm/gcm_profile_service_factory.h" #include "chrome/common/url_constants.h" @@ -161,9 +162,9 @@ void GcmInternalsUIMessageHandler::ReturnResults( gcm::GCMProfileService::GetGCMEnabledState(profile))); if (profile_service) { device_info->SetString("signedInUserName", - profile_service->SignedInUserName()); + profile_service->driver()->SignedInUserName()); device_info->SetBoolean("gcmClientReady", - profile_service->IsGCMClientReady()); + profile_service->driver()->IsGCMClientReady()); } if (stats) { results.SetBoolean("isRecording", stats->is_recording); @@ -234,10 +235,10 @@ void GcmInternalsUIMessageHandler::RequestAllInfo( if (!profile_service) { ReturnResults(profile, NULL, NULL); - } else if (profile_service->SignedInUserName().empty()) { + } else if (profile_service->driver()->SignedInUserName().empty()) { ReturnResults(profile, profile_service, NULL); } else { - profile_service->GetGCMStatistics( + profile_service->driver()->GetGCMStatistics( base::Bind(&GcmInternalsUIMessageHandler::RequestGCMStatisticsFinished, weak_ptr_factory_.GetWeakPtr()), clear_logs); @@ -263,12 +264,12 @@ void GcmInternalsUIMessageHandler::SetRecording(const base::ListValue* args) { ReturnResults(profile, NULL, NULL); return; } - if (profile_service->SignedInUserName().empty()) { + if (profile_service->driver()->SignedInUserName().empty()) { ReturnResults(profile, profile_service, NULL); return; } // Get fresh stats after changing recording setting. - profile_service->SetGCMRecording( + profile_service->driver()->SetGCMRecording( base::Bind( &GcmInternalsUIMessageHandler::RequestGCMStatisticsFinished, weak_ptr_factory_.GetWeakPtr()), diff --git a/google_apis/gcm/gcm_client.h b/google_apis/gcm/gcm_client.h index dc659673f567aa..178b18f11d5809 100644 --- a/google_apis/gcm/gcm_client.h +++ b/google_apis/gcm/gcm_client.h @@ -41,6 +41,8 @@ class GCM_EXPORT GCMClient { SUCCESS, // Invalid parameter. INVALID_PARAMETER, + // GCM is disabled. + GCM_DISABLED, // Profile not signed in. NOT_SIGNED_IN, // Previous asynchronous operation is still pending to finish. Certain diff --git a/sync/notifier/gcm_network_channel.cc b/sync/notifier/gcm_network_channel.cc index 654123a72b62e7..59f1a575cc7087 100644 --- a/sync/notifier/gcm_network_channel.cc +++ b/sync/notifier/gcm_network_channel.cc @@ -421,6 +421,7 @@ std::string GCMNetworkChannelDiagnostic::GCMClientResultToString( ENUM_CASE(gcm::GCMClient::NOT_SIGNED_IN); ENUM_CASE(gcm::GCMClient::INVALID_PARAMETER); ENUM_CASE(gcm::GCMClient::ASYNC_OPERATION_PENDING); + ENUM_CASE(gcm::GCMClient::GCM_DISABLED); } NOTREACHED(); return "";