This source file includes following definitions.
- weak_factory_
- Initialize
- RequestToken
- InvalidateToken
- Register
- SetMessageReceiver
- RequestTokenFinished
- RegisterFinished
- OnIncomingMessage
- weak_factory_
- CreateDelegate
- CoreInitializationDone
- RequestToken
- OnGetTokenSuccess
- OnGetTokenFailure
- InvalidateToken
- Register
- RegisterFinished
- SubscribeForIncomingMessages
- ShutdownHandler
- OnMessage
- OnMessagesDeleted
- OnSendError
#include "base/bind.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
#include "chrome/browser/invalidation/gcm_invalidation_bridge.h"
#include "chrome/browser/invalidation/invalidation_auth_provider.h"
#include "chrome/browser/services/gcm/gcm_profile_service.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "components/signin/core/browser/profile_oauth2_token_service.h"
#include "components/signin/core/browser/signin_manager.h"
#include "google_apis/gaia/gaia_constants.h"
namespace invalidation {
namespace {
const char kInvalidationsSenderId[] = "ipc.invalidation@gmail.com";
const char kInvalidationsAppId[] = "com.google.chrome.invalidations";
const char kContentKey[] = "content";
const char kEchoTokenKey[] = "echo-token";
}
class GCMInvalidationBridge::Core : public syncer::GCMNetworkChannelDelegate,
public base::NonThreadSafe {
public:
Core(base::WeakPtr<GCMInvalidationBridge> bridge,
scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner);
virtual ~Core();
virtual void Initialize() OVERRIDE;
virtual void RequestToken(RequestTokenCallback callback) OVERRIDE;
virtual void InvalidateToken(const std::string& token) OVERRIDE;
virtual void Register(RegisterCallback callback) OVERRIDE;
virtual void SetMessageReceiver(MessageCallback callback) OVERRIDE;
void RequestTokenFinished(RequestTokenCallback callback,
const GoogleServiceAuthError& error,
const std::string& token);
void RegisterFinished(RegisterCallback callback,
const std::string& registration_id,
gcm::GCMClient::Result result);
void OnIncomingMessage(const std::string& message,
const std::string& echo_token);
private:
base::WeakPtr<GCMInvalidationBridge> bridge_;
scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner_;
MessageCallback message_callback_;
base::WeakPtrFactory<Core> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(Core);
};
GCMInvalidationBridge::Core::Core(
base::WeakPtr<GCMInvalidationBridge> bridge,
scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner)
: bridge_(bridge),
ui_thread_task_runner_(ui_thread_task_runner),
weak_factory_(this) {
DetachFromThread();
}
GCMInvalidationBridge::Core::~Core() {}
void GCMInvalidationBridge::Core::Initialize() {
DCHECK(CalledOnValidThread());
ui_thread_task_runner_->PostTask(
FROM_HERE,
base::Bind(&GCMInvalidationBridge::CoreInitializationDone,
bridge_,
weak_factory_.GetWeakPtr(),
base::ThreadTaskRunnerHandle::Get()));
}
void GCMInvalidationBridge::Core::RequestToken(RequestTokenCallback callback) {
DCHECK(CalledOnValidThread());
ui_thread_task_runner_->PostTask(
FROM_HERE,
base::Bind(&GCMInvalidationBridge::RequestToken, bridge_, callback));
}
void GCMInvalidationBridge::Core::InvalidateToken(const std::string& token) {
DCHECK(CalledOnValidThread());
ui_thread_task_runner_->PostTask(
FROM_HERE,
base::Bind(&GCMInvalidationBridge::InvalidateToken, bridge_, token));
}
void GCMInvalidationBridge::Core::Register(RegisterCallback callback) {
DCHECK(CalledOnValidThread());
ui_thread_task_runner_->PostTask(
FROM_HERE,
base::Bind(&GCMInvalidationBridge::Register, bridge_, callback));
}
void GCMInvalidationBridge::Core::SetMessageReceiver(MessageCallback callback) {
message_callback_ = callback;
ui_thread_task_runner_->PostTask(
FROM_HERE,
base::Bind(&GCMInvalidationBridge::SubscribeForIncomingMessages,
bridge_));
}
void GCMInvalidationBridge::Core::RequestTokenFinished(
RequestTokenCallback callback,
const GoogleServiceAuthError& error,
const std::string& token) {
DCHECK(CalledOnValidThread());
callback.Run(error, token);
}
void GCMInvalidationBridge::Core::RegisterFinished(
RegisterCallback callback,
const std::string& registration_id,
gcm::GCMClient::Result result) {
DCHECK(CalledOnValidThread());
callback.Run(registration_id, result);
}
void GCMInvalidationBridge::Core::OnIncomingMessage(
const std::string& message,
const std::string& echo_token) {
DCHECK(!message_callback_.is_null());
message_callback_.Run(message, echo_token);
}
GCMInvalidationBridge::GCMInvalidationBridge(
gcm::GCMProfileService* gcm_profile_service,
InvalidationAuthProvider* auth_provider)
: OAuth2TokenService::Consumer("gcm_network_channel"),
gcm_profile_service_(gcm_profile_service),
auth_provider_(auth_provider),
subscribed_for_incoming_messages_(false),
weak_factory_(this) {}
GCMInvalidationBridge::~GCMInvalidationBridge() {
if (subscribed_for_incoming_messages_)
gcm_profile_service_->RemoveAppHandler(kInvalidationsAppId);
}
scoped_ptr<syncer::GCMNetworkChannelDelegate>
GCMInvalidationBridge::CreateDelegate() {
DCHECK(CalledOnValidThread());
scoped_ptr<syncer::GCMNetworkChannelDelegate> core(new Core(
weak_factory_.GetWeakPtr(), base::ThreadTaskRunnerHandle::Get()));
return core.Pass();
}
void GCMInvalidationBridge::CoreInitializationDone(
base::WeakPtr<Core> core,
scoped_refptr<base::SingleThreadTaskRunner> core_thread_task_runner) {
DCHECK(CalledOnValidThread());
core_ = core;
core_thread_task_runner_ = core_thread_task_runner;
}
void GCMInvalidationBridge::RequestToken(
syncer::GCMNetworkChannelDelegate::RequestTokenCallback callback) {
DCHECK(CalledOnValidThread());
if (access_token_request_ != NULL) {
GoogleServiceAuthError error(GoogleServiceAuthError::REQUEST_CANCELED);
std::string access_token;
core_thread_task_runner_->PostTask(
FROM_HERE,
base::Bind(&GCMInvalidationBridge::Core::RequestTokenFinished,
core_,
request_token_callback_,
error,
access_token));
}
request_token_callback_ = callback;
OAuth2TokenService::ScopeSet scopes;
scopes.insert(GaiaConstants::kChromeSyncOAuth2Scope);
access_token_request_ = auth_provider_->GetTokenService()->StartRequest(
auth_provider_->GetAccountId(), scopes, this);
}
void GCMInvalidationBridge::OnGetTokenSuccess(
const OAuth2TokenService::Request* request,
const std::string& access_token,
const base::Time& expiration_time) {
DCHECK(CalledOnValidThread());
DCHECK_EQ(access_token_request_, request);
core_thread_task_runner_->PostTask(
FROM_HERE,
base::Bind(&GCMInvalidationBridge::Core::RequestTokenFinished,
core_,
request_token_callback_,
GoogleServiceAuthError::AuthErrorNone(),
access_token));
request_token_callback_.Reset();
access_token_request_.reset();
}
void GCMInvalidationBridge::OnGetTokenFailure(
const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error) {
DCHECK(CalledOnValidThread());
DCHECK_EQ(access_token_request_, request);
core_thread_task_runner_->PostTask(
FROM_HERE,
base::Bind(&GCMInvalidationBridge::Core::RequestTokenFinished,
core_,
request_token_callback_,
error,
std::string()));
request_token_callback_.Reset();
access_token_request_.reset();
}
void GCMInvalidationBridge::InvalidateToken(const std::string& token) {
DCHECK(CalledOnValidThread());
OAuth2TokenService::ScopeSet scopes;
scopes.insert(GaiaConstants::kChromeSyncOAuth2Scope);
auth_provider_->GetTokenService()->InvalidateToken(
auth_provider_->GetAccountId(), scopes, token);
}
void GCMInvalidationBridge::Register(
syncer::GCMNetworkChannelDelegate::RegisterCallback callback) {
DCHECK(CalledOnValidThread());
if (gcm_profile_service_ == NULL)
return;
std::vector<std::string> sender_ids;
sender_ids.push_back(kInvalidationsSenderId);
gcm_profile_service_->Register(
kInvalidationsAppId,
sender_ids,
base::Bind(&GCMInvalidationBridge::RegisterFinished,
weak_factory_.GetWeakPtr(),
callback));
}
void GCMInvalidationBridge::RegisterFinished(
syncer::GCMNetworkChannelDelegate::RegisterCallback callback,
const std::string& registration_id,
gcm::GCMClient::Result result) {
DCHECK(CalledOnValidThread());
core_thread_task_runner_->PostTask(
FROM_HERE,
base::Bind(&GCMInvalidationBridge::Core::RegisterFinished,
core_,
callback,
registration_id,
result));
}
void GCMInvalidationBridge::SubscribeForIncomingMessages() {
if (gcm_profile_service_ == NULL)
return;
DCHECK(!subscribed_for_incoming_messages_);
gcm_profile_service_->AddAppHandler(kInvalidationsAppId, this);
subscribed_for_incoming_messages_ = true;
}
void GCMInvalidationBridge::ShutdownHandler() {
}
void GCMInvalidationBridge::OnMessage(
const std::string& app_id,
const gcm::GCMClient::IncomingMessage& message) {
gcm::GCMClient::MessageData::const_iterator it;
std::string content;
std::string echo_token;
it = message.data.find(kContentKey);
if (it != message.data.end())
content = it->second;
it = message.data.find(kEchoTokenKey);
if (it != message.data.end())
echo_token = it->second;
core_thread_task_runner_->PostTask(
FROM_HERE,
base::Bind(&GCMInvalidationBridge::Core::OnIncomingMessage,
core_,
content,
echo_token));
}
void GCMInvalidationBridge::OnMessagesDeleted(const std::string& app_id) {
}
void GCMInvalidationBridge::OnSendError(
const std::string& app_id,
const gcm::GCMClient::SendErrorDetails& send_error_details) {
NOTREACHED();
}
}