| // 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()) { |
| // DefaultNetworkChanged will get called when a network becomes connected. |
| 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::DefaultNetworkChanged(const NetworkState* network) { |
| if (!network) |
| return; // Still no default (connected) network. |
| |
| NetworkHandler::Get()->network_state_handler() |
| ->RemoveObserver(this, FROM_HERE); |
| if (GetRequestContext()) |
| DoPrewarm(); |
| } |
| |
| 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(GaiaUrls::GetInstance()->client_login_url()); |
| urls.push_back(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 |