Commit 0b06ae6c authored by jianli@chromium.org's avatar jianli@chromium.org

[GCM] Introduce GCMClientFactory to create GCMClient for GCMProfileService

We used to call GCMClient::Get() to get the single instance. This did not
work when we need to pass some initialization data from browser to it.
GCMClientFactory is introduced such that GCMClient instance can be
created, initialized and used in GCMProfileService::IOWorker.

BUG=284553
TEST=existing tests

Review URL: https://codereview.chromium.org/135903005

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@245447 0039d316-1c4b-4281-b951-d872f2087c98
parent 43eb220a
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/services/gcm/gcm_client_factory.h"
#include "base/files/file_path.h"
#include "base/lazy_instance.h"
#include "base/threading/sequenced_worker_pool.h"
#include "content/public/browser/browser_thread.h"
#include "google_apis/gcm/gcm_client_impl.h"
namespace gcm {
namespace {
static base::LazyInstance<GCMClientImpl>::Leaky g_gcm_client =
LAZY_INSTANCE_INITIALIZER;
static bool g_gcm_client_initialized = false;
static GCMClientFactory::TestingFactoryFunction g_gcm_client_factory = NULL;
static GCMClient* g_gcm_client_override = NULL;
} // namespace
// static
GCMClient* GCMClientFactory::GetClient() {
if (g_gcm_client_override)
return g_gcm_client_override;
if (g_gcm_client_factory) {
g_gcm_client_override = g_gcm_client_factory();
return g_gcm_client_override;
}
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
GCMClientImpl* client = g_gcm_client.Pointer();
if (!g_gcm_client_initialized) {
// TODO(jianli): get gcm store path.
base::FilePath gcm_store_path;
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));
client->Initialize(gcm_store_path, blocking_task_runner);
g_gcm_client_initialized = true;
}
return client;
}
// static
void GCMClientFactory::SetTestingFactory(TestingFactoryFunction factory) {
if (g_gcm_client_override) {
delete g_gcm_client_override;
g_gcm_client_override = NULL;
}
g_gcm_client_factory = factory;
}
GCMClientFactory::GCMClientFactory() {
}
GCMClientFactory::~GCMClientFactory() {
}
} // namespace gcm
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_SERVICES_GCM_GCM_CLIENT_FACTORY_H_
#define CHROME_BROWSER_SERVICES_GCM_GCM_CLIENT_FACTORY_H_
#include "base/macros.h"
class Profile;
namespace gcm {
class GCMClient;
class GCMClientFactory {
public:
// Returns a single instance of GCMClient.
// This should be called from IO thread.
static GCMClient* GetClient();
// Passes a mocked instance for testing purpose.
typedef GCMClient* (*TestingFactoryFunction)();
static void SetTestingFactory(TestingFactoryFunction factory);
private:
GCMClientFactory();
~GCMClientFactory();
DISALLOW_COPY_AND_ASSIGN(GCMClientFactory);
};
} // namespace gcm
#endif // CHROME_BROWSER_SERVICES_GCM_GCM_CLIENT_FACTORY_H_
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_system.h" #include "chrome/browser/extensions/extension_system.h"
#include "chrome/browser/extensions/state_store.h" #include "chrome/browser/extensions/state_store.h"
#include "chrome/browser/services/gcm/gcm_client_factory.h"
#include "chrome/browser/services/gcm/gcm_event_router.h" #include "chrome/browser/services/gcm/gcm_event_router.h"
#include "chrome/browser/signin/signin_manager.h" #include "chrome/browser/signin/signin_manager.h"
#include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/browser/signin/signin_manager_factory.h"
...@@ -200,7 +201,6 @@ class GCMProfileService::IOWorker ...@@ -200,7 +201,6 @@ class GCMProfileService::IOWorker
GCMClient::Result result) OVERRIDE; GCMClient::Result result) OVERRIDE;
virtual GCMClient::CheckinInfo GetCheckinInfo() const OVERRIDE; virtual GCMClient::CheckinInfo GetCheckinInfo() const OVERRIDE;
virtual void OnLoadingCompleted() OVERRIDE; virtual void OnLoadingCompleted() OVERRIDE;
virtual base::TaskRunner* GetFileTaskRunner() OVERRIDE;
void CheckGCMClientLoading(); void CheckGCMClientLoading();
void SetUser(const std::string& username); void SetUser(const std::string& username);
...@@ -221,8 +221,13 @@ class GCMProfileService::IOWorker ...@@ -221,8 +221,13 @@ class GCMProfileService::IOWorker
friend class base::RefCountedThreadSafe<IOWorker>; friend class base::RefCountedThreadSafe<IOWorker>;
virtual ~IOWorker(); virtual ~IOWorker();
void Initialize();
const base::WeakPtr<GCMProfileService> service_; const base::WeakPtr<GCMProfileService> service_;
// Not owned.
GCMClient* gcm_client_;
// The username (email address) of the signed-in user. // The username (email address) of the signed-in user.
std::string username_; std::string username_;
...@@ -233,12 +238,23 @@ class GCMProfileService::IOWorker ...@@ -233,12 +238,23 @@ class GCMProfileService::IOWorker
GCMProfileService::IOWorker::IOWorker( GCMProfileService::IOWorker::IOWorker(
const base::WeakPtr<GCMProfileService>& service) const base::WeakPtr<GCMProfileService>& service)
: service_(service) { : service_(service),
gcm_client_(NULL) {
content::BrowserThread::PostTask(
content::BrowserThread::IO,
FROM_HERE,
base::Bind(&GCMProfileService::IOWorker::Initialize, this));
} }
GCMProfileService::IOWorker::~IOWorker() { GCMProfileService::IOWorker::~IOWorker() {
} }
void GCMProfileService::IOWorker::Initialize() {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
gcm_client_ = GCMClientFactory::GetClient();
}
void GCMProfileService::IOWorker::OnCheckInFinished( void GCMProfileService::IOWorker::OnCheckInFinished(
const GCMClient::CheckinInfo& checkin_info, const GCMClient::CheckinInfo& checkin_info,
GCMClient::Result result) { GCMClient::Result result) {
...@@ -340,18 +356,13 @@ void GCMProfileService::IOWorker::OnLoadingCompleted() { ...@@ -340,18 +356,13 @@ void GCMProfileService::IOWorker::OnLoadingCompleted() {
service_)); service_));
} }
base::TaskRunner* GCMProfileService::IOWorker::GetFileTaskRunner() {
// TODO(jianli): to be implemented.
return NULL;
}
void GCMProfileService::IOWorker::CheckGCMClientLoading() { void GCMProfileService::IOWorker::CheckGCMClientLoading() {
content::BrowserThread::PostTask( content::BrowserThread::PostTask(
content::BrowserThread::UI, content::BrowserThread::UI,
FROM_HERE, FROM_HERE,
base::Bind(&GCMProfileService::CheckGCMClientLoadingFinished, base::Bind(&GCMProfileService::CheckGCMClientLoadingFinished,
service_, service_,
GCMClient::Get()->IsLoading())); gcm_client_->IsLoading()));
} }
void GCMProfileService::IOWorker::SetUser(const std::string& username) { void GCMProfileService::IOWorker::SetUser(const std::string& username) {
...@@ -359,7 +370,7 @@ void GCMProfileService::IOWorker::SetUser(const std::string& username) { ...@@ -359,7 +370,7 @@ void GCMProfileService::IOWorker::SetUser(const std::string& username) {
DCHECK(username_.empty() && !username.empty()); DCHECK(username_.empty() && !username.empty());
username_ = username; username_ = username;
GCMClient::Get()->SetUserDelegate(username_, this); gcm_client_->SetUserDelegate(username_, this);
} }
void GCMProfileService::IOWorker::RemoveUser(const std::string& username) { void GCMProfileService::IOWorker::RemoveUser(const std::string& username) {
...@@ -369,13 +380,13 @@ void GCMProfileService::IOWorker::RemoveUser(const std::string& username) { ...@@ -369,13 +380,13 @@ void GCMProfileService::IOWorker::RemoveUser(const std::string& username) {
if (username_.empty()) if (username_.empty())
return; return;
username_.clear(); username_.clear();
GCMClient::Get()->SetUserDelegate(username_, NULL); gcm_client_->SetUserDelegate(username_, NULL);
} }
void GCMProfileService::IOWorker::CheckIn() { void GCMProfileService::IOWorker::CheckIn() {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
GCMClient::Get()->CheckIn(username_); gcm_client_->CheckIn(username_);
} }
void GCMProfileService::IOWorker::SetCheckinInfo( void GCMProfileService::IOWorker::SetCheckinInfo(
...@@ -399,14 +410,14 @@ void GCMProfileService::IOWorker::Register( ...@@ -399,14 +410,14 @@ void GCMProfileService::IOWorker::Register(
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
DCHECK(!username_.empty() && checkin_info_.IsValid()); DCHECK(!username_.empty() && checkin_info_.IsValid());
GCMClient::Get()->Register(username_, app_id, cert, sender_ids); gcm_client_->Register(username_, app_id, cert, sender_ids);
} }
void GCMProfileService::IOWorker::Unregister(const std::string& app_id) { void GCMProfileService::IOWorker::Unregister(const std::string& app_id) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
DCHECK(!username_.empty() && checkin_info_.IsValid()); DCHECK(!username_.empty() && checkin_info_.IsValid());
GCMClient::Get()->Unregister(username_, app_id); gcm_client_->Unregister(username_, app_id);
} }
void GCMProfileService::IOWorker::Send( void GCMProfileService::IOWorker::Send(
...@@ -416,7 +427,7 @@ void GCMProfileService::IOWorker::Send( ...@@ -416,7 +427,7 @@ void GCMProfileService::IOWorker::Send(
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
DCHECK(!username_.empty() && checkin_info_.IsValid()); DCHECK(!username_.empty() && checkin_info_.IsValid());
GCMClient::Get()->Send(username_, app_id, receiver_id, message); gcm_client_->Send(username_, app_id, receiver_id, message);
} }
GCMProfileService::RegistrationInfo::RegistrationInfo() { GCMProfileService::RegistrationInfo::RegistrationInfo() {
...@@ -465,6 +476,7 @@ GCMProfileService::GCMProfileService(Profile* profile) ...@@ -465,6 +476,7 @@ GCMProfileService::GCMProfileService(Profile* profile)
testing_delegate_(NULL), testing_delegate_(NULL),
weak_ptr_factory_(this) { weak_ptr_factory_(this) {
DCHECK(!profile->IsOffTheRecord()); DCHECK(!profile->IsOffTheRecord());
Init(); Init();
} }
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "chrome/browser/extensions/state_store.h" #include "chrome/browser/extensions/state_store.h"
#include "chrome/browser/extensions/test_extension_service.h" #include "chrome/browser/extensions/test_extension_service.h"
#include "chrome/browser/extensions/test_extension_system.h" #include "chrome/browser/extensions/test_extension_system.h"
#include "chrome/browser/services/gcm/gcm_client_factory.h"
#include "chrome/browser/services/gcm/gcm_client_mock.h" #include "chrome/browser/services/gcm/gcm_client_mock.h"
#include "chrome/browser/services/gcm/gcm_event_router.h" #include "chrome/browser/services/gcm/gcm_event_router.h"
#include "chrome/browser/services/gcm/gcm_profile_service.h" #include "chrome/browser/services/gcm/gcm_profile_service.h"
...@@ -135,7 +136,7 @@ class GCMProfileServiceTest : public testing::Test, ...@@ -135,7 +136,7 @@ class GCMProfileServiceTest : public testing::Test,
#endif #endif
// Mock a GCMClient. // Mock a GCMClient.
GCMClient::SetTestingFactory(&GCMProfileServiceTest::BuildGCMClient); GCMClientFactory::SetTestingFactory(&GCMProfileServiceTest::BuildGCMClient);
// Mock a GCMEventRouter. // Mock a GCMEventRouter.
gcm_event_router_mock_.reset(new GCMEventRouterMock(this)); gcm_event_router_mock_.reset(new GCMEventRouterMock(this));
...@@ -244,7 +245,7 @@ class GCMProfileServiceTest : public testing::Test, ...@@ -244,7 +245,7 @@ class GCMProfileServiceTest : public testing::Test,
}; };
static GCMClientMock* GetGCMClientMock() { static GCMClientMock* GetGCMClientMock() {
return static_cast<GCMClientMock*>(GCMClient::Get()); return static_cast<GCMClientMock*>(GCMClientFactory::GetClient());
} }
class ScopedGCMClientMockSimulateServerError { class ScopedGCMClientMockSimulateServerError {
......
...@@ -1938,6 +1938,8 @@ ...@@ -1938,6 +1938,8 @@
'browser/search_engines/template_url_service_observer.h', 'browser/search_engines/template_url_service_observer.h',
'browser/search_engines/util.cc', 'browser/search_engines/util.cc',
'browser/search_engines/util.h', 'browser/search_engines/util.h',
'browser/services/gcm/gcm_client_factory.cc',
'browser/services/gcm/gcm_client_factory.h',
'browser/services/gcm/gcm_event_router.h', 'browser/services/gcm/gcm_event_router.h',
'browser/services/gcm/gcm_profile_service.cc', 'browser/services/gcm/gcm_profile_service.cc',
'browser/services/gcm/gcm_profile_service.h', 'browser/services/gcm/gcm_profile_service.h',
......
...@@ -48,7 +48,6 @@ class GCMClientDelegate : public GCMClient::Delegate { ...@@ -48,7 +48,6 @@ class GCMClientDelegate : public GCMClient::Delegate {
return GCMClient::CheckinInfo(); return GCMClient::CheckinInfo();
} }
virtual void OnLoadingCompleted() OVERRIDE {} virtual void OnLoadingCompleted() OVERRIDE {}
virtual base::TaskRunner* GetFileTaskRunner() OVERRIDE { return NULL; }
private: private:
std::string username_; std::string username_;
......
...@@ -4,20 +4,8 @@ ...@@ -4,20 +4,8 @@
#include "google_apis/gcm/gcm_client.h" #include "google_apis/gcm/gcm_client.h"
#include "base/lazy_instance.h"
#include "google_apis/gcm/gcm_client_impl.h"
namespace gcm { namespace gcm {
namespace {
static base::LazyInstance<GCMClientImpl>::Leaky g_gcm_client =
LAZY_INSTANCE_INITIALIZER;
static GCMClient::TestingFactoryFunction g_gcm_client_factory = NULL;
static GCMClient* g_gcm_client_override = NULL;
} // namespace
GCMClient::OutgoingMessage::OutgoingMessage() GCMClient::OutgoingMessage::OutgoingMessage()
: time_to_live(0) { : time_to_live(0) {
} }
...@@ -31,24 +19,10 @@ GCMClient::IncomingMessage::IncomingMessage() { ...@@ -31,24 +19,10 @@ GCMClient::IncomingMessage::IncomingMessage() {
GCMClient::IncomingMessage::~IncomingMessage() { GCMClient::IncomingMessage::~IncomingMessage() {
} }
// static GCMClient::GCMClient() {
GCMClient* GCMClient::Get() {
if (g_gcm_client_override)
return g_gcm_client_override;
if (g_gcm_client_factory) {
g_gcm_client_override = g_gcm_client_factory();
return g_gcm_client_override;
}
return g_gcm_client.Pointer();
} }
// static GCMClient::~GCMClient() {
void GCMClient::SetTestingFactory(TestingFactoryFunction factory) {
if (g_gcm_client_override) {
delete g_gcm_client_override;
g_gcm_client_override = NULL;
}
g_gcm_client_factory = factory;
} }
} // namespace gcm } // namespace gcm
...@@ -12,10 +12,6 @@ ...@@ -12,10 +12,6 @@
#include "base/basictypes.h" #include "base/basictypes.h"
#include "google_apis/gcm/base/gcm_export.h" #include "google_apis/gcm/base/gcm_export.h"
namespace base {
class TaskRunner;
}
namespace gcm { namespace gcm {
// Interface that encapsulates the network communications with the Google Cloud // Interface that encapsulates the network communications with the Google Cloud
...@@ -129,19 +125,10 @@ class GCM_EXPORT GCMClient { ...@@ -129,19 +125,10 @@ class GCM_EXPORT GCMClient {
// Called when the loading from the persistent store is done. The loading // Called when the loading from the persistent store is done. The loading
// is triggered asynchronously when GCMClient is created. // is triggered asynchronously when GCMClient is created.
virtual void OnLoadingCompleted() = 0; virtual void OnLoadingCompleted() = 0;
// Returns a task runner for file operations that may block. This is used
// in writing to or reading from the persistent store.
virtual base::TaskRunner* GetFileTaskRunner() = 0;
}; };
// Returns the single instance. Multiple profiles share the same client GCMClient();
// that makes use of the same MCS connection. virtual ~GCMClient();
static GCMClient* Get();
// Passes a mocked instance for testing purpose.
typedef GCMClient* (*TestingFactoryFunction)();
static void SetTestingFactory(TestingFactoryFunction factory);
// Sets the delegate to interact with related to a specific user. // Sets the delegate to interact with related to a specific user.
// |username|: the username (email address) used to check in with the server. // |username|: the username (email address) used to check in with the server.
...@@ -189,9 +176,6 @@ class GCM_EXPORT GCMClient { ...@@ -189,9 +176,6 @@ class GCM_EXPORT GCMClient {
// Returns true if the loading from the persistent store is still in progress. // Returns true if the loading from the persistent store is still in progress.
virtual bool IsLoading() const = 0; virtual bool IsLoading() const = 0;
protected:
virtual ~GCMClient() {}
}; };
} // namespace gcm } // namespace gcm
......
...@@ -20,7 +20,7 @@ namespace gcm { ...@@ -20,7 +20,7 @@ namespace gcm {
class GCMStore; class GCMStore;
class UserList; class UserList;
class GCMClientImpl : public GCMClient { class GCM_EXPORT GCMClientImpl : public GCMClient {
public: public:
GCMClientImpl(); GCMClientImpl();
virtual ~GCMClientImpl(); virtual ~GCMClientImpl();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment