1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/chromeos/login/auth/auth_prewarmer.h" 6 7#include "chrome/browser/chrome_notification_types.h" 8#include "chrome/browser/chromeos/profiles/profile_helper.h" 9#include "chrome/browser/net/chrome_url_request_context.h" 10#include "chrome/browser/net/preconnect.h" 11#include "chromeos/network/network_handler.h" 12#include "chromeos/network/network_state.h" 13#include "chromeos/network/network_state_handler.h" 14#include "content/public/browser/browser_thread.h" 15#include "google_apis/gaia/gaia_urls.h" 16#include "url/gurl.h" 17 18namespace chromeos { 19 20AuthPrewarmer::AuthPrewarmer() 21 : doing_prewarm_(false) { 22} 23 24AuthPrewarmer::~AuthPrewarmer() { 25 if (registrar_.IsRegistered( 26 this, 27 chrome::NOTIFICATION_PROFILE_URL_REQUEST_CONTEXT_GETTER_INITIALIZED, 28 content::Source<Profile>(ProfileHelper::GetSigninProfile()))) { 29 registrar_.Remove( 30 this, 31 chrome::NOTIFICATION_PROFILE_URL_REQUEST_CONTEXT_GETTER_INITIALIZED, 32 content::Source<Profile>(ProfileHelper::GetSigninProfile())); 33 } 34 NetworkHandler::Get()->network_state_handler()->RemoveObserver(this, 35 FROM_HERE); 36} 37 38void AuthPrewarmer::PrewarmAuthentication( 39 const base::Closure& completion_callback) { 40 if (doing_prewarm_) { 41 LOG(ERROR) << "PrewarmAuthentication called twice."; 42 return; 43 } 44 doing_prewarm_ = true; 45 completion_callback_ = completion_callback; 46 if (GetRequestContext() && IsNetworkConnected()) { 47 DoPrewarm(); 48 return; 49 } 50 if (!IsNetworkConnected()) { 51 // DefaultNetworkChanged will get called when a network becomes connected. 52 NetworkHandler::Get()->network_state_handler() 53 ->AddObserver(this, FROM_HERE); 54 } 55 if (!GetRequestContext()) { 56 registrar_.Add( 57 this, 58 chrome::NOTIFICATION_PROFILE_URL_REQUEST_CONTEXT_GETTER_INITIALIZED, 59 content::Source<Profile>(ProfileHelper::GetSigninProfile())); 60 } 61} 62 63void AuthPrewarmer::DefaultNetworkChanged(const NetworkState* network) { 64 if (!network) 65 return; // Still no default (connected) network. 66 67 NetworkHandler::Get()->network_state_handler() 68 ->RemoveObserver(this, FROM_HERE); 69 if (GetRequestContext()) 70 DoPrewarm(); 71} 72 73void AuthPrewarmer::Observe(int type, 74 const content::NotificationSource& source, 75 const content::NotificationDetails& details) { 76 switch (type) { 77 case chrome::NOTIFICATION_PROFILE_URL_REQUEST_CONTEXT_GETTER_INITIALIZED: 78 registrar_.Remove( 79 this, 80 chrome::NOTIFICATION_PROFILE_URL_REQUEST_CONTEXT_GETTER_INITIALIZED, 81 content::Source<Profile>(ProfileHelper::GetSigninProfile())); 82 if (IsNetworkConnected()) 83 DoPrewarm(); 84 break; 85 default: 86 NOTREACHED(); 87 } 88} 89 90void AuthPrewarmer::DoPrewarm() { 91 const int kConnectionsNeeded = 1; 92 93 std::vector<GURL> urls; 94 urls.push_back(GaiaUrls::GetInstance()->client_login_url()); 95 urls.push_back(GaiaUrls::GetInstance()->service_login_url()); 96 97 for (size_t i = 0; i < urls.size(); ++i) { 98 chrome_browser_net::PreconnectOnUIThread( 99 urls[i], 100 urls[i], 101 chrome_browser_net::UrlInfo::EARLY_LOAD_MOTIVATED, 102 kConnectionsNeeded, 103 GetRequestContext()); 104 } 105 if (!completion_callback_.is_null()) { 106 content::BrowserThread::PostTask(content::BrowserThread::UI, 107 FROM_HERE, 108 completion_callback_); 109 } 110} 111 112bool AuthPrewarmer::IsNetworkConnected() const { 113 NetworkStateHandler* nsh = NetworkHandler::Get()->network_state_handler(); 114 return (nsh->ConnectedNetworkByType(NetworkTypePattern::Default()) != NULL); 115} 116 117net::URLRequestContextGetter* AuthPrewarmer::GetRequestContext() const { 118 return ProfileHelper::GetSigninProfile()->GetRequestContext(); 119} 120 121} // namespace chromeos 122