blob: 3fe03a17bc8dc4b1ecd98332b08ea83d955699c0 [file] [log] [blame]
// Copyright 2013 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/login/auth_prewarmer.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/net/chrome_url_request_context.h"
#include "chrome/browser/net/preconnect.h"
#include "chromeos/network/network_handler.h"
#include "chromeos/network/network_state.h"
#include "chromeos/network/network_state_handler.h"
#include "chromeos/network/shill_property_util.h"
#include "content/public/browser/browser_thread.h"
#include "google_apis/gaia/gaia_urls.h"
#include "url/gurl.h"
namespace chromeos {
AuthPrewarmer::AuthPrewarmer()
: doing_prewarm_(false) {
}
AuthPrewarmer::~AuthPrewarmer() {
if (registrar_.IsRegistered(
this,
chrome::NOTIFICATION_PROFILE_URL_REQUEST_CONTEXT_GETTER_INITIALIZED,
content::Source<Profile>(ProfileHelper::GetSigninProfile()))) {
registrar_.Remove(
this,
chrome::NOTIFICATION_PROFILE_URL_REQUEST_CONTEXT_GETTER_INITIALIZED,
content::Source<Profile>(ProfileHelper::GetSigninProfile()));
}
NetworkHandler::Get()->network_state_handler()->RemoveObserver(this,
FROM_HERE);
}
void AuthPrewarmer::PrewarmAuthentication(
const base::Closure& completion_callback) {
if (doing_prewarm_) {
LOG(ERROR) << "PrewarmAuthentication called twice.";
return;
}
doing_prewarm_ = true;
completion_callback_ = completion_callback;
if (GetRequestContext() && IsNetworkConnected()) {
DoPrewarm();
return;
}
if (!IsNetworkConnected())
NetworkHandler::Get()->network_state_handler()->AddObserver(this,
FROM_HERE);
if (!GetRequestContext()) {
registrar_.Add(
this,
chrome::NOTIFICATION_PROFILE_URL_REQUEST_CONTEXT_GETTER_INITIALIZED,
content::Source<Profile>(ProfileHelper::GetSigninProfile()));
}
}
void AuthPrewarmer::NetworkManagerChanged() {
if (IsNetworkConnected()) {
NetworkHandler::Get()->network_state_handler()->RemoveObserver(this,
FROM_HERE);
if (GetRequestContext())
DoPrewarm();
}
}
void AuthPrewarmer::DefaultNetworkChanged(const NetworkState* network) {
NetworkManagerChanged();
}
void AuthPrewarmer::Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
switch (type) {
case chrome::NOTIFICATION_PROFILE_URL_REQUEST_CONTEXT_GETTER_INITIALIZED:
registrar_.Remove(
this,
chrome::NOTIFICATION_PROFILE_URL_REQUEST_CONTEXT_GETTER_INITIALIZED,
content::Source<Profile>(ProfileHelper::GetSigninProfile()));
if (IsNetworkConnected())
DoPrewarm();
break;
default:
NOTREACHED();
}
}
void AuthPrewarmer::DoPrewarm() {
const int kConnectionsNeeded = 1;
std::vector<GURL> urls;
urls.push_back(GURL(GaiaUrls::GetInstance()->client_login_url()));
urls.push_back(GURL(GaiaUrls::GetInstance()->service_login_url()));
for (size_t i = 0; i < urls.size(); ++i) {
chrome_browser_net::PreconnectOnUIThread(
urls[i],
urls[i],
chrome_browser_net::UrlInfo::EARLY_LOAD_MOTIVATED,
kConnectionsNeeded,
GetRequestContext());
}
if (!completion_callback_.is_null()) {
content::BrowserThread::PostTask(content::BrowserThread::UI,
FROM_HERE,
completion_callback_);
}
}
bool AuthPrewarmer::IsNetworkConnected() const {
NetworkStateHandler* nsh = NetworkHandler::Get()->network_state_handler();
return (nsh->ConnectedNetworkByType(NetworkTypePattern::Default()) != NULL);
}
net::URLRequestContextGetter* AuthPrewarmer::GetRequestContext() const {
return ProfileHelper::GetSigninProfile()->GetRequestContext();
}
} // namespace chromeos