blob: 253a8339e8f51adc59b3f58772e1b5586cb28827 [file] [log] [blame]
// Copyright (c) 2012 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/chromeos/settings/device_oauth2_token_service_factory.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/message_loop/message_loop.h"
#include "base/tracked_objects.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/settings/device_oauth2_token_service.h"
#include "chrome/browser/chromeos/settings/token_encryptor.h"
#include "chromeos/cryptohome/system_salt_getter.h"
#include "content/public/browser/browser_thread.h"
namespace chromeos {
namespace {
DeviceOAuth2TokenServiceFactory* g_factory = NULL;
} // namespace
DeviceOAuth2TokenServiceFactory::DeviceOAuth2TokenServiceFactory()
: initialized_(false),
token_service_(NULL),
weak_ptr_factory_(this) {
}
DeviceOAuth2TokenServiceFactory::~DeviceOAuth2TokenServiceFactory() {
delete token_service_;
}
// static
void DeviceOAuth2TokenServiceFactory::Get(const GetCallback& callback) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
if (!g_factory) {
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(callback,
static_cast<DeviceOAuth2TokenService*>(NULL)));
return;
}
g_factory->RunAsync(callback);
}
// static
void DeviceOAuth2TokenServiceFactory::Initialize() {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
DCHECK(!g_factory);
g_factory = new DeviceOAuth2TokenServiceFactory;
g_factory->CreateTokenService();
}
// static
void DeviceOAuth2TokenServiceFactory::Shutdown() {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
if (g_factory) {
delete g_factory;
g_factory = NULL;
}
}
void DeviceOAuth2TokenServiceFactory::CreateTokenService() {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
SystemSaltGetter::Get()->GetSystemSalt(
base::Bind(&DeviceOAuth2TokenServiceFactory::DidGetSystemSalt,
weak_ptr_factory_.GetWeakPtr()));
}
void DeviceOAuth2TokenServiceFactory::DidGetSystemSalt(
const std::string& system_salt) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
DCHECK(!token_service_);
if (system_salt.empty()) {
LOG(ERROR) << "Failed to get the system salt";
} else {
token_service_= new DeviceOAuth2TokenService(
g_browser_process->system_request_context(),
g_browser_process->local_state(),
new CryptohomeTokenEncryptor(system_salt));
}
// Mark that the factory is initialized.
initialized_ = true;
// Run callbacks regardless of whether token_service_ is created or not,
// but don't run callbacks immediately. Each callback would cause an
// interesting action, hence running them consecutively could be
// potentially expensive and dangerous.
while (!pending_callbacks_.empty()) {
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(pending_callbacks_.front(), token_service_));
pending_callbacks_.pop();
}
}
void DeviceOAuth2TokenServiceFactory::RunAsync(const GetCallback& callback) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
if (initialized_) {
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(callback, token_service_));
return;
}
pending_callbacks_.push(callback);
}
} // namespace chromeos