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