[GCM] Make GCMProfileService create and own GCMClient
We're switching to one GCMClient per profile.
BUG=284553
TEST=existing tests
Review URL: https://codereview.chromium.org/149803009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@249824 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/services/gcm/gcm_client_factory.cc b/chrome/browser/services/gcm/gcm_client_factory.cc
index f928393..ef78865 100644
--- a/chrome/browser/services/gcm/gcm_client_factory.cc
+++ b/chrome/browser/services/gcm/gcm_client_factory.cc
@@ -4,139 +4,12 @@
#include "chrome/browser/services/gcm/gcm_client_factory.h"
-#include "base/files/file_path.h"
-#include "base/lazy_instance.h"
-#include "base/logging.h"
-#include "base/path_service.h"
-#include "base/threading/sequenced_worker_pool.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/io_thread.h"
-#include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_paths.h"
-#include "chrome/common/chrome_version_info.h"
-#include "content/public/browser/browser_thread.h"
#include "google_apis/gcm/gcm_client_impl.h"
-#include "net/url_request/url_request_context_getter.h"
namespace gcm {
-namespace {
-
-static bool g_gcm_client_io_task_posted = false;
-static base::LazyInstance<GCMClientImpl>::Leaky g_gcm_client =
- LAZY_INSTANCE_INITIALIZER;
-static GCMClientFactory::TestingFactoryFunction g_gcm_client_factory = NULL;
-static GCMClient* g_gcm_client_override = NULL;
-
-checkin_proto::ChromeBuildProto_Platform GetPlatform() {
-#if defined(OS_WIN)
- return checkin_proto::ChromeBuildProto_Platform_PLATFORM_WIN;
-#elif defined(OS_MACOSX)
- return checkin_proto::ChromeBuildProto_Platform_PLATFORM_MAC;
-#elif defined(OS_CHROMEOS)
- return checkin_proto::ChromeBuildProto_Platform_PLATFORM_CROS;
-#elif defined(OS_LINUX)
- return checkin_proto::ChromeBuildProto_Platform_PLATFORM_LINUX;
-#else
- // For all other platforms, return as LINUX.
- return checkin_proto::ChromeBuildProto_Platform_PLATFORM_LINUX;
-#endif
-}
-
-std::string GetVersion() {
- chrome::VersionInfo version_info;
- return version_info.Version();
-}
-
-checkin_proto::ChromeBuildProto_Channel GetChannel() {
- chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
- switch (channel) {
- case chrome::VersionInfo::CHANNEL_UNKNOWN:
- return checkin_proto::ChromeBuildProto_Channel_CHANNEL_UNKNOWN;
- case chrome::VersionInfo::CHANNEL_CANARY:
- return checkin_proto::ChromeBuildProto_Channel_CHANNEL_CANARY;
- case chrome::VersionInfo::CHANNEL_DEV:
- return checkin_proto::ChromeBuildProto_Channel_CHANNEL_DEV;
- case chrome::VersionInfo::CHANNEL_BETA:
- return checkin_proto::ChromeBuildProto_Channel_CHANNEL_BETA;
- case chrome::VersionInfo::CHANNEL_STABLE:
- return checkin_proto::ChromeBuildProto_Channel_CHANNEL_STABLE;
- default:
- NOTREACHED();
- return checkin_proto::ChromeBuildProto_Channel_CHANNEL_UNKNOWN;
- };
-}
-
-void BuildClientFromIO(const scoped_refptr<net::URLRequestContextGetter>&
- url_request_context_getter) {
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
- DCHECK(g_gcm_client == NULL);
-
- checkin_proto::ChromeBuildProto chrome_build_proto;
- chrome_build_proto.set_platform(GetPlatform());
- chrome_build_proto.set_chrome_version(GetVersion());
- chrome_build_proto.set_channel(GetChannel());
-
- base::FilePath gcm_store_path;
- CHECK(PathService::Get(chrome::DIR_USER_DATA, &gcm_store_path));
- gcm_store_path = gcm_store_path.Append(chrome::kGCMStoreDirname);
-
- scoped_refptr<base::SequencedWorkerPool> worker_pool(
- content::BrowserThread::GetBlockingPool());
- scoped_refptr<base::SequencedTaskRunner> blocking_task_runner(
- worker_pool->GetSequencedTaskRunnerWithShutdownBehavior(
- worker_pool->GetSequenceToken(),
- base::SequencedWorkerPool::SKIP_ON_SHUTDOWN));
-
- g_gcm_client.Pointer()->Initialize(chrome_build_proto,
- gcm_store_path,
- blocking_task_runner,
- url_request_context_getter);
-}
-
-} // namespace
-
-// static
-void GCMClientFactory::BuildClientFromUI() {
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
-
- if (g_gcm_client_factory) {
- if (!g_gcm_client_override)
- g_gcm_client_override = g_gcm_client_factory();
- return;
- }
-
- if (g_gcm_client_io_task_posted)
- return;
- g_gcm_client_io_task_posted = true;
-
- // system_url_request_context_getter can only be retrieved from
- // UI thread.
- scoped_refptr<net::URLRequestContextGetter> url_request_context_getter(
- g_browser_process->io_thread()->system_url_request_context_getter());
-
- content::BrowserThread::PostTask(
- content::BrowserThread::IO,
- FROM_HERE,
- base::Bind(&BuildClientFromIO, url_request_context_getter));
-}
-
-// static
-GCMClient* GCMClientFactory::GetClient() {
- // TODO(jianli): Make test code also get the client on IO thread.
- if (g_gcm_client_override)
- return g_gcm_client_override;
-
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
- DCHECK(!(g_gcm_client == NULL));
-
- return g_gcm_client.Pointer();
-}
-
-// static
-void GCMClientFactory::SetTestingFactory(TestingFactoryFunction factory) {
- g_gcm_client_factory = factory;
- BuildClientFromUI();
+scoped_ptr<GCMClient> GCMClientFactory::BuildInstance() {
+ return scoped_ptr<GCMClient>(new GCMClientImpl());
}
GCMClientFactory::GCMClientFactory() {
diff --git a/chrome/browser/services/gcm/gcm_client_factory.h b/chrome/browser/services/gcm/gcm_client_factory.h
index e2914f0..9112399 100644
--- a/chrome/browser/services/gcm/gcm_client_factory.h
+++ b/chrome/browser/services/gcm/gcm_client_factory.h
@@ -6,11 +6,7 @@
#define CHROME_BROWSER_SERVICES_GCM_GCM_CLIENT_FACTORY_H_
#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-
-namespace net {
-class URLRequestContextGetter;
-}
+#include "base/memory/scoped_ptr.h"
namespace gcm {
@@ -18,22 +14,14 @@
class GCMClientFactory {
public:
- // Creates the single instance of GCMClient if not yet created.
- // Called on UI thread.
- static void BuildClientFromUI();
+ GCMClientFactory();
+ virtual ~GCMClientFactory();
- // Returns a single instance of GCMClient.
- // This should be called on IO thread.
- static GCMClient* GetClient();
-
- // Passes a mocked instance for testing purpose.
- typedef GCMClient* (*TestingFactoryFunction)();
- static void SetTestingFactory(TestingFactoryFunction factory);
+ // Creates a new instance of GCMClient. The testing code could override this
+ // to provide a mocked instance.
+ virtual scoped_ptr<GCMClient> BuildInstance();
private:
- GCMClientFactory();
- ~GCMClientFactory();
-
DISALLOW_COPY_AND_ASSIGN(GCMClientFactory);
};
diff --git a/chrome/browser/services/gcm/gcm_client_mock.cc b/chrome/browser/services/gcm/gcm_client_mock.cc
index e2e3bc3..4945a27b 100644
--- a/chrome/browser/services/gcm/gcm_client_mock.cc
+++ b/chrome/browser/services/gcm/gcm_client_mock.cc
@@ -25,14 +25,22 @@
} // namespace
-GCMClientMock::GCMClientMock()
- : ready_(true),
+GCMClientMock::GCMClientMock(Status status)
+ : status_(status),
simulate_server_error_(false) {
}
GCMClientMock::~GCMClientMock() {
}
+void GCMClientMock::Initialize(
+ const checkin_proto::ChromeBuildProto& chrome_build_proto,
+ const base::FilePath& store_path,
+ const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner,
+ const scoped_refptr<net::URLRequestContextGetter>&
+ url_request_context_getter) {
+}
+
void GCMClientMock::SetUserDelegate(const std::string& username,
Delegate* delegate) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
@@ -98,7 +106,7 @@
}
bool GCMClientMock::IsReady() const {
- return ready_;
+ return status_ == READY;
}
void GCMClientMock::ReceiveMessage(const std::string& username,
@@ -129,15 +137,11 @@
app_id));
}
-void GCMClientMock::SetReady(bool ready) {
+void GCMClientMock::SetReady() {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ DCHECK_EQ(status_, NOT_READY);
- if (ready == ready_)
- return;
- ready_ = ready;
-
- if (!ready_)
- return;
+ status_ = READY;
content::BrowserThread::PostTask(
content::BrowserThread::IO,
FROM_HERE,
diff --git a/chrome/browser/services/gcm/gcm_client_mock.h b/chrome/browser/services/gcm/gcm_client_mock.h
index f15b5f0..62397ee 100644
--- a/chrome/browser/services/gcm/gcm_client_mock.h
+++ b/chrome/browser/services/gcm/gcm_client_mock.h
@@ -14,11 +14,22 @@
class GCMClientMock : public GCMClient {
public:
- GCMClientMock();
+ enum Status {
+ NOT_READY,
+ READY
+ };
+
+ explicit GCMClientMock(Status status);
virtual ~GCMClientMock();
// Overridden from GCMClient:
// Called on IO thread.
+ virtual void Initialize(
+ const checkin_proto::ChromeBuildProto& chrome_build_proto,
+ const base::FilePath& store_path,
+ const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner,
+ const scoped_refptr<net::URLRequestContextGetter>&
+ url_request_context_getter) OVERRIDE;
virtual void SetUserDelegate(const std::string& username,
Delegate* delegate) OVERRIDE;
virtual void CheckIn(const std::string& username) OVERRIDE;
@@ -45,7 +56,8 @@
simulate_server_error_ = simulate_server_error;
}
- void SetReady(bool ready);
+ // Can only transition from non-ready to ready.
+ void SetReady();
static CheckinInfo GetCheckinInfoFromUsername(const std::string& username);
static std::string GetRegistrationIdFromSenderIds(
@@ -74,7 +86,7 @@
std::map<std::string, Delegate*> delegates_;
- bool ready_;
+ Status status_;
// The testing code could set this to simulate the server error in order to
// test the error scenario.
diff --git a/chrome/browser/services/gcm/gcm_profile_service.cc b/chrome/browser/services/gcm/gcm_profile_service.cc
index 731a699..5740892 100644
--- a/chrome/browser/services/gcm/gcm_profile_service.cc
+++ b/chrome/browser/services/gcm/gcm_profile_service.cc
@@ -5,9 +5,12 @@
#include "chrome/browser/services/gcm/gcm_profile_service.h"
#include "base/base64.h"
+#include "base/files/file_path.h"
#include "base/logging.h"
+#include "base/path_service.h"
#include "base/prefs/pref_service.h"
#include "base/strings/string_number_conversions.h"
+#include "base/threading/sequenced_worker_pool.h"
#include "chrome/browser/chrome_notification_types.h"
#if !defined(OS_ANDROID)
#include "chrome/browser/extensions/api/gcm/gcm_api.h"
@@ -18,6 +21,8 @@
#include "chrome/browser/services/gcm/gcm_event_router.h"
#include "chrome/browser/signin/signin_manager.h"
#include "chrome/browser/signin/signin_manager_factory.h"
+#include "chrome/common/chrome_constants.h"
+#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_version_info.h"
#include "chrome/common/pref_names.h"
#include "components/user_prefs/pref_registry_syncable.h"
@@ -27,15 +32,60 @@
#include "content/public/browser/notification_source.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/extension.h"
+#include "google_apis/gcm/protocol/android_checkin.pb.h"
+#include "net/url_request/url_request_context_getter.h"
using extensions::Extension;
namespace gcm {
+namespace {
+
const char kRegistrationKey[] = "gcm.registration";
const char kSendersKey[] = "senders";
const char kRegistrationIDKey[] = "reg_id";
+checkin_proto::ChromeBuildProto_Platform GetPlatform() {
+#if defined(OS_WIN)
+ return checkin_proto::ChromeBuildProto_Platform_PLATFORM_WIN;
+#elif defined(OS_MACOSX)
+ return checkin_proto::ChromeBuildProto_Platform_PLATFORM_MAC;
+#elif defined(OS_CHROMEOS)
+ return checkin_proto::ChromeBuildProto_Platform_PLATFORM_CROS;
+#elif defined(OS_LINUX)
+ return checkin_proto::ChromeBuildProto_Platform_PLATFORM_LINUX;
+#else
+ // For all other platforms, return as LINUX.
+ return checkin_proto::ChromeBuildProto_Platform_PLATFORM_LINUX;
+#endif
+}
+
+std::string GetVersion() {
+ chrome::VersionInfo version_info;
+ return version_info.Version();
+}
+
+checkin_proto::ChromeBuildProto_Channel GetChannel() {
+ chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
+ switch (channel) {
+ case chrome::VersionInfo::CHANNEL_UNKNOWN:
+ return checkin_proto::ChromeBuildProto_Channel_CHANNEL_UNKNOWN;
+ case chrome::VersionInfo::CHANNEL_CANARY:
+ return checkin_proto::ChromeBuildProto_Channel_CHANNEL_CANARY;
+ case chrome::VersionInfo::CHANNEL_DEV:
+ return checkin_proto::ChromeBuildProto_Channel_CHANNEL_DEV;
+ case chrome::VersionInfo::CHANNEL_BETA:
+ return checkin_proto::ChromeBuildProto_Channel_CHANNEL_BETA;
+ case chrome::VersionInfo::CHANNEL_STABLE:
+ return checkin_proto::ChromeBuildProto_Channel_CHANNEL_STABLE;
+ default:
+ NOTREACHED();
+ return checkin_proto::ChromeBuildProto_Channel_CHANNEL_UNKNOWN;
+ };
+}
+
+} // namespace
+
// Helper class to save tasks to run until we're ready to execute them.
class GCMProfileService::DelayedTaskController {
public:
@@ -203,7 +253,11 @@
virtual void OnGCMReady() OVERRIDE;
// Called on IO thread.
- void Initialize();
+ void Initialize(
+ scoped_ptr<GCMClient> gcm_client,
+ const base::FilePath& store_path,
+ const scoped_refptr<net::URLRequestContextGetter>&
+ url_request_context_getter);
void SetUser(const std::string& username);
void RemoveUser();
void CheckIn();
@@ -223,8 +277,7 @@
const base::WeakPtr<GCMProfileService> service_;
- // Not owned.
- GCMClient* gcm_client_;
+ scoped_ptr<GCMClient> gcm_client_;
// The username (email address) of the signed-in user.
std::string username_;
@@ -236,18 +289,38 @@
GCMProfileService::IOWorker::IOWorker(
const base::WeakPtr<GCMProfileService>& service)
- : service_(service),
- gcm_client_(NULL) {
+ : service_(service) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
}
GCMProfileService::IOWorker::~IOWorker() {
}
-void GCMProfileService::IOWorker::Initialize() {
+void GCMProfileService::IOWorker::Initialize(
+ scoped_ptr<GCMClient> gcm_client,
+ const base::FilePath& store_path,
+ const scoped_refptr<net::URLRequestContextGetter>&
+ url_request_context_getter) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
- gcm_client_ = GCMClientFactory::GetClient();
+ gcm_client_ = gcm_client.Pass();
+
+ checkin_proto::ChromeBuildProto chrome_build_proto;
+ chrome_build_proto.set_platform(GetPlatform());
+ chrome_build_proto.set_chrome_version(GetVersion());
+ chrome_build_proto.set_channel(GetChannel());
+
+ scoped_refptr<base::SequencedWorkerPool> worker_pool(
+ content::BrowserThread::GetBlockingPool());
+ scoped_refptr<base::SequencedTaskRunner> blocking_task_runner(
+ worker_pool->GetSequencedTaskRunnerWithShutdownBehavior(
+ worker_pool->GetSequenceToken(),
+ base::SequencedWorkerPool::SKIP_ON_SHUTDOWN));
+
+ gcm_client_->Initialize(chrome_build_proto,
+ store_path,
+ blocking_task_runner,
+ url_request_context_getter);
content::BrowserThread::PostTask(
content::BrowserThread::UI,
@@ -482,7 +555,7 @@
io_worker_));
}
-void GCMProfileService::Initialize() {
+void GCMProfileService::Initialize(GCMClientFactory* gcm_client_factory) {
delayed_task_controller_.reset(new DelayedTaskController);
// This has to be done first since CheckIn depends on it.
@@ -492,12 +565,20 @@
js_event_router_.reset(new extensions::GcmJsEventRouter(profile_));
#endif
+ scoped_ptr<GCMClient> gcm_client(gcm_client_factory->BuildInstance());
+ scoped_refptr<net::URLRequestContextGetter> url_request_context_getter =
+ profile_->GetRequestContext();
+
// This initializes GCMClient and also does the check to find out if GCMClient
// is ready.
content::BrowserThread::PostTask(
content::BrowserThread::IO,
FROM_HERE,
- base::Bind(&GCMProfileService::IOWorker::Initialize, io_worker_));
+ base::Bind(&GCMProfileService::IOWorker::Initialize,
+ io_worker_,
+ base::Passed(&gcm_client),
+ profile_->GetPath().Append(chrome::kGCMStoreDirname),
+ url_request_context_getter));
// In case that the profile has been signed in before GCMProfileService is
// created.
diff --git a/chrome/browser/services/gcm/gcm_profile_service.h b/chrome/browser/services/gcm/gcm_profile_service.h
index ba87f307..ff6c511c 100644
--- a/chrome/browser/services/gcm/gcm_profile_service.h
+++ b/chrome/browser/services/gcm/gcm_profile_service.h
@@ -34,6 +34,7 @@
namespace gcm {
+class GCMClientFactory;
class GCMEventRouter;
class GCMProfileServiceTestConsumer;
@@ -63,7 +64,7 @@
explicit GCMProfileService(Profile* profile);
virtual ~GCMProfileService();
- void Initialize();
+ void Initialize(GCMClientFactory* gcm_client_factory);
// Registers |sender_id| for an app. A registration ID will be returned by
// the GCM server.
diff --git a/chrome/browser/services/gcm/gcm_profile_service_factory.cc b/chrome/browser/services/gcm/gcm_profile_service_factory.cc
index c116c1af..71e5546 100644
--- a/chrome/browser/services/gcm/gcm_profile_service_factory.cc
+++ b/chrome/browser/services/gcm/gcm_profile_service_factory.cc
@@ -37,13 +37,12 @@
BrowserContextKeyedService* GCMProfileServiceFactory::BuildServiceInstanceFor(
content::BrowserContext* context) const {
- GCMClientFactory::BuildClientFromUI();
-
Profile* profile = static_cast<Profile*>(context);
if (!gcm::GCMProfileService::IsGCMEnabled(profile))
return NULL;
GCMProfileService* service = new GCMProfileService(profile);
- service->Initialize();
+ GCMClientFactory gcm_client_factory;
+ service->Initialize(&gcm_client_factory);
return service;
}
diff --git a/chrome/browser/services/gcm/gcm_profile_service_unittest.cc b/chrome/browser/services/gcm/gcm_profile_service_unittest.cc
index 5a8f9ad..96310b2 100644
--- a/chrome/browser/services/gcm/gcm_profile_service_unittest.cc
+++ b/chrome/browser/services/gcm/gcm_profile_service_unittest.cc
@@ -7,7 +7,6 @@
#include "base/bind.h"
#include "base/command_line.h"
-#include "base/debug/leak_annotations.h"
#include "base/message_loop/message_loop.h"
#include "base/prefs/pref_service.h"
#include "base/run_loop.h"
@@ -207,6 +206,31 @@
GCMClient::Result send_error_result_;
};
+class FakeGCMClientFactory : public GCMClientFactory {
+ public:
+ explicit FakeGCMClientFactory(GCMClientMock::Status gcm_client_initial_status)
+ : gcm_client_initial_status_(gcm_client_initial_status),
+ gcm_client_(NULL) {
+ }
+
+ virtual ~FakeGCMClientFactory() {
+ }
+
+ virtual scoped_ptr<GCMClient> BuildInstance() OVERRIDE {
+ DCHECK(!gcm_client_);
+ gcm_client_ = new GCMClientMock(gcm_client_initial_status_);
+ return scoped_ptr<GCMClient>(gcm_client_);
+ }
+
+ GCMClientMock* gcm_client() const { return gcm_client_; }
+
+ private:
+ GCMClientMock::Status gcm_client_initial_status_;
+ GCMClientMock* gcm_client_;
+
+ DISALLOW_COPY_AND_ASSIGN(FakeGCMClientFactory);
+};
+
class GCMProfileServiceTestConsumer : public GCMProfileService::TestingDelegate{
public:
static BrowserContextKeyedService* BuildFakeSigninManager(
@@ -223,6 +247,7 @@
: waiter_(waiter),
extension_service_(NULL),
signin_manager_(NULL),
+ gcm_client_initial_status_(GCMClientMock::READY),
registration_result_(GCMClient::SUCCESS),
has_persisted_registration_info_(false),
send_result_(GCMClient::SUCCESS) {
@@ -299,7 +324,9 @@
GCMProfileServiceFactory::GetInstance()->SetTestingFactoryAndUse(
profile(), &GCMProfileServiceTestConsumer::BuildGCMProfileService));
gcm_profile_service->set_testing_delegate(this);
- gcm_profile_service->Initialize();
+ gcm_client_factory_.reset(
+ new FakeGCMClientFactory(gcm_client_initial_status_));
+ gcm_profile_service->Initialize(gcm_client_factory_.get());
}
void CheckIn(const std::string& username) {
@@ -371,6 +398,10 @@
return GCMProfileServiceFactory::GetForProfile(profile());
}
+ GCMClientMock* GetGCMClient() const {
+ return gcm_client_factory_->gcm_client();
+ }
+
const std::string& GetUsername() const {
return GetGCMProfileService()->username_;
}
@@ -385,6 +416,10 @@
return gcm_event_router_.get();
}
+ void set_gcm_client_initial_status(GCMClientMock::Status status) {
+ gcm_client_initial_status_ = status;
+ }
+
GCMClient::CheckinInfo checkin_info() const { return checkin_info_; }
const std::string& registration_id() const { return registration_id_; }
GCMClient::Result registration_result() const { return registration_result_; }
@@ -418,6 +453,9 @@
ExtensionService* extension_service_; // Not owned.
FakeSigninManager* signin_manager_; // Not owned.
scoped_ptr<FakeGCMEventRouter> gcm_event_router_;
+ scoped_ptr<FakeGCMClientFactory> gcm_client_factory_;
+
+ GCMClientMock::Status gcm_client_initial_status_;
GCMClient::CheckinInfo checkin_info_;
@@ -433,11 +471,6 @@
class GCMProfileServiceTest : public testing::Test {
public:
- static GCMClient* BuildGCMClient() {
- ANNOTATE_SCOPED_MEMORY_LEAK;
- return new GCMClientMock();
- }
-
GCMProfileServiceTest() {
}
@@ -461,9 +494,6 @@
Encryptor::UseMockKeychain(true);
#endif
- // Mock a GCMClient.
- GCMClientFactory::SetTestingFactory(&GCMProfileServiceTest::BuildGCMClient);
-
// Create a main profile consumer.
consumer_.reset(new GCMProfileServiceTestConsumer(&waiter_));
}
@@ -508,21 +538,21 @@
DISALLOW_COPY_AND_ASSIGN(GCMProfileServiceTest);
};
-static GCMClientMock* GetGCMClientMock() {
- return static_cast<GCMClientMock*>(GCMClientFactory::GetClient());
-}
-
class ScopedGCMClientMockSimulateServerError {
public:
- ScopedGCMClientMockSimulateServerError() {
- GetGCMClientMock()->set_simulate_server_error(true);
+ ScopedGCMClientMockSimulateServerError(
+ GCMProfileServiceTestConsumer* consumer)
+ : consumer_(consumer) {
+ consumer_->GetGCMClient()->set_simulate_server_error(true);
}
~ScopedGCMClientMockSimulateServerError() {
- GetGCMClientMock()->set_simulate_server_error(false);
+ consumer_->GetGCMClient()->set_simulate_server_error(false);
}
private:
+ GCMProfileServiceTestConsumer* consumer_;
+
DISALLOW_COPY_AND_ASSIGN(ScopedGCMClientMockSimulateServerError);
};
@@ -629,7 +659,8 @@
// Check-in should not reach the server. Forcing GCMClient server error should
// help catch this.
- ScopedGCMClientMockSimulateServerError gcm_client_simulate_server_error;
+ ScopedGCMClientMockSimulateServerError gcm_client_simulate_server_error(
+ consumer());
// Recreate GCMProfileService to test reading the check-in info from the
// prefs store.
@@ -787,7 +818,8 @@
// Register should not reach the server. Forcing GCMClient server error should
// help catch this.
- ScopedGCMClientMockSimulateServerError gcm_client_simulate_server_error;
+ ScopedGCMClientMockSimulateServerError gcm_client_simulate_server_error(
+ consumer());
// This should read the registration info from the extension's state store.
// We still need to wait since the reading from state store might happen at
@@ -815,8 +847,8 @@
// preparation to call register 2nd time.
consumer()->clear_registration_result();
- // Mark that GCMClient is not ready.
- GetGCMClientMock()->SetReady(false);
+ // Needs to create a GCMClient instance that is not ready initiallly.
+ consumer()->set_gcm_client_initial_status(GCMClientMock::NOT_READY);
// Simulate start-up by recreating GCMProfileService.
consumer()->CreateGCMProfileServiceInstance();
@@ -832,7 +864,7 @@
EXPECT_EQ(GCMClient::UNKNOWN_ERROR, consumer()->registration_result());
// Register operation will be invoked after GCMClient becomes ready.
- GetGCMClientMock()->SetReady(true);
+ consumer()->GetGCMClient()->SetReady();
WaitUntilCompleted();
EXPECT_EQ(old_registration_id, consumer()->registration_id());
EXPECT_EQ(GCMClient::SUCCESS, consumer()->registration_result());
@@ -933,7 +965,8 @@
GCMClient::IncomingMessage message;
message.data["key1"] = "value1";
message.data["key2"] = "value2";
- GetGCMClientMock()->ReceiveMessage(kTestingUsername, kTestingAppId, message);
+ consumer()->GetGCMClient()->ReceiveMessage(
+ kTestingUsername, kTestingAppId, message);
WaitUntilCompleted();
EXPECT_EQ(FakeGCMEventRouter::MESSAGE_EVENT,
consumer()->gcm_event_router()->received_event());
@@ -948,7 +981,8 @@
GCMClient::IncomingMessage message;
message.data["key1"] = "value1";
message.data["key2"] = "value2";
- GetGCMClientMock()->ReceiveMessage(kTestingUsername, kTestingAppId, message);
+ consumer()->GetGCMClient()->ReceiveMessage(
+ kTestingUsername, kTestingAppId, message);
PumpIOLoop();
EXPECT_EQ(FakeGCMEventRouter::NO_EVENT,
@@ -957,7 +991,7 @@
}
TEST_F(GCMProfileServiceSingleProfileTest, MessagesDeleted) {
- GetGCMClientMock()->DeleteMessages(kTestingUsername, kTestingAppId);
+ consumer()->GetGCMClient()->DeleteMessages(kTestingUsername, kTestingAppId);
WaitUntilCompleted();
EXPECT_EQ(FakeGCMEventRouter::MESSAGES_DELETED_EVENT,
consumer()->gcm_event_router()->received_event());
@@ -968,7 +1002,7 @@
// This will trigger check-out.
consumer()->signin_manager()->SignOut();
- GetGCMClientMock()->DeleteMessages(kTestingUsername, kTestingAppId);
+ consumer()->GetGCMClient()->DeleteMessages(kTestingUsername, kTestingAppId);
PumpIOLoop();
EXPECT_EQ(FakeGCMEventRouter::NO_EVENT,
@@ -1107,12 +1141,13 @@
GCMClient::IncomingMessage message;
message.data["key1"] = "value1";
message.data["key2"] = "value2";
- GetGCMClientMock()->ReceiveMessage(kTestingUsername, kTestingAppId, message);
+ consumer()->GetGCMClient()->ReceiveMessage(
+ kTestingUsername, kTestingAppId, message);
// Trigger an incoming message for the same app in another profile.
GCMClient::IncomingMessage message2;
message2.data["foo"] = "bar";
- GetGCMClientMock()->ReceiveMessage(
+ consumer2()->GetGCMClient()->ReceiveMessage(
kTestingUsername2, kTestingAppId, message2);
WaitUntilCompleted();
@@ -1132,7 +1167,7 @@
GCMClient::IncomingMessage message3;
message3.data["bar1"] = "foo1";
message3.data["bar2"] = "foo2";
- GetGCMClientMock()->ReceiveMessage(
+ consumer2()->GetGCMClient()->ReceiveMessage(
kTestingUsername2, kTestingAppId2, message3);
WaitUntilCompleted();
@@ -1203,7 +1238,7 @@
GCMClient::IncomingMessage in_message;
in_message.data["in1"] = "in_data1";
in_message.data["in1_2"] = "in_data1_2";
- GetGCMClientMock()->ReceiveMessage(
+ consumer()->GetGCMClient()->ReceiveMessage(
kTestingUsername, kTestingAppId, in_message);
WaitUntilCompleted();
@@ -1218,13 +1253,13 @@
// profile.
GCMClient::IncomingMessage in_message2;
in_message2.data["in2"] = "in_data2";
- GetGCMClientMock()->ReceiveMessage(
+ consumer2()->GetGCMClient()->ReceiveMessage(
kTestingUsername2, kTestingAppId2, in_message2);
GCMClient::IncomingMessage in_message3;
in_message3.data["in3"] = "in_data3";
in_message3.data["in3_2"] = "in_data3_2";
- GetGCMClientMock()->ReceiveMessage(
+ consumer2()->GetGCMClient()->ReceiveMessage(
kTestingUsername2, kTestingAppId, in_message3);
consumer2()->gcm_event_router()->clear_results();
@@ -1273,7 +1308,7 @@
// Incoming message will be ingored for the signed-out profile.
GCMClient::IncomingMessage in_message4;
in_message4.data["in4"] = "in_data4";
- GetGCMClientMock()->ReceiveMessage(
+ consumer()->GetGCMClient()->ReceiveMessage(
kTestingUsername, kTestingAppId, in_message4);
consumer()->gcm_event_router()->clear_results();
@@ -1284,7 +1319,7 @@
EXPECT_TRUE(consumer()->gcm_event_router()->app_id().empty());
// Deleted messages event will be ingored for the signed-out profile.
- GetGCMClientMock()->DeleteMessages(kTestingUsername, kTestingAppId);
+ consumer()->GetGCMClient()->DeleteMessages(kTestingUsername, kTestingAppId);
PumpIOLoop();
@@ -1293,7 +1328,8 @@
EXPECT_TRUE(consumer()->gcm_event_router()->app_id().empty());
// Deleted messages event will go through for another signed-in profile.
- GetGCMClientMock()->DeleteMessages(kTestingUsername2, kTestingAppId2);
+ consumer2()->GetGCMClient()->DeleteMessages(
+ kTestingUsername2, kTestingAppId2);
consumer2()->gcm_event_router()->clear_results();
WaitUntilCompleted();
@@ -1327,7 +1363,7 @@
WaitUntilCompleted();
// Incoming message will still be ingored for the signed-out user.
- GetGCMClientMock()->ReceiveMessage(
+ consumer()->GetGCMClient()->ReceiveMessage(
kTestingUsername, kTestingAppId, in_message4);
consumer()->gcm_event_router()->clear_results();
@@ -1340,7 +1376,7 @@
// Incoming message will go through for the new signed-in user.
GCMClient::IncomingMessage in_message5;
in_message5.data["in5"] = "in_data5";
- GetGCMClientMock()->ReceiveMessage(
+ consumer()->GetGCMClient()->ReceiveMessage(
kTestingUsername3, kTestingAppId, in_message5);
consumer()->gcm_event_router()->clear_results();
diff --git a/google_apis/gcm/gcm_client.h b/google_apis/gcm/gcm_client.h
index 46ba561..c9203e8 100644
--- a/google_apis/gcm/gcm_client.h
+++ b/google_apis/gcm/gcm_client.h
@@ -12,6 +12,21 @@
#include "base/basictypes.h"
#include "google_apis/gcm/base/gcm_export.h"
+template <class T> class scoped_refptr;
+
+namespace base {
+class FilePath;
+class SequencedTaskRunner;
+}
+
+namespace checkin_proto {
+class ChromeBuildProto;
+}
+
+namespace net {
+class URLRequestContextGetter;
+}
+
namespace gcm {
// Interface that encapsulates the network communications with the Google Cloud
@@ -133,6 +148,14 @@
GCMClient();
virtual ~GCMClient();
+ // Begins initialization of the GCM Client.
+ virtual void Initialize(
+ const checkin_proto::ChromeBuildProto& chrome_build_proto,
+ const base::FilePath& store_path,
+ const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner,
+ const scoped_refptr<net::URLRequestContextGetter>&
+ url_request_context_getter) = 0;
+
// Sets the delegate to interact with related to a specific user.
// |username|: the username (email address) used to check in with the server.
// |delegate|: the delegate whose methods will be called asynchronously in
diff --git a/google_apis/gcm/gcm_client_impl.cc b/google_apis/gcm/gcm_client_impl.cc
index 92402e17..bf78cf6 100644
--- a/google_apis/gcm/gcm_client_impl.cc
+++ b/google_apis/gcm/gcm_client_impl.cc
@@ -141,7 +141,7 @@
void GCMClientImpl::Initialize(
const checkin_proto::ChromeBuildProto& chrome_build_proto,
const base::FilePath& path,
- scoped_refptr<base::SequencedTaskRunner> blocking_task_runner,
+ const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner,
const scoped_refptr<net::URLRequestContextGetter>&
url_request_context_getter) {
DCHECK_EQ(UNINITIALIZED, state_);
diff --git a/google_apis/gcm/gcm_client_impl.h b/google_apis/gcm/gcm_client_impl.h
index a6bac754f..e20d86b 100644
--- a/google_apis/gcm/gcm_client_impl.h
+++ b/google_apis/gcm/gcm_client_impl.h
@@ -23,8 +23,6 @@
namespace base {
class Clock;
-class FilePath;
-class SequencedTaskRunner;
} // namespace base
namespace net {
@@ -48,15 +46,13 @@
GCMClientImpl();
virtual ~GCMClientImpl();
- // Begins initialization of the GCM Client.
- void Initialize(
- const checkin_proto::ChromeBuildProto& chrome_build_proto,
- const base::FilePath& path,
- scoped_refptr<base::SequencedTaskRunner> blocking_task_runner,
- const scoped_refptr<net::URLRequestContextGetter>&
- url_request_context_getter);
-
// Overridden from GCMClient:
+ virtual void Initialize(
+ const checkin_proto::ChromeBuildProto& chrome_build_proto,
+ const base::FilePath& store_path,
+ const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner,
+ const scoped_refptr<net::URLRequestContextGetter>&
+ url_request_context_getter) OVERRIDE;
virtual void SetUserDelegate(const std::string& username,
Delegate* delegate) OVERRIDE;
virtual void CheckIn(const std::string& username) OVERRIDE;