1 // Copyright 2013 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_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 "chromeos/network/shill_property_util.h" 15 #include "content/public/browser/browser_thread.h" 16 #include "google_apis/gaia/gaia_urls.h" 17 #include "url/gurl.h" 18 19 namespace chromeos { 20 21 AuthPrewarmer::AuthPrewarmer() 22 : doing_prewarm_(false) { 23 } 24 25 AuthPrewarmer::~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 39 void 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 64 void 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 74 void 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 91 void 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 113 bool AuthPrewarmer::IsNetworkConnected() const { 114 NetworkStateHandler* nsh = NetworkHandler::Get()->network_state_handler(); 115 return (nsh->ConnectedNetworkByType(NetworkTypePattern::Default()) != NULL); 116 } 117 118 net::URLRequestContextGetter* AuthPrewarmer::GetRequestContext() const { 119 return ProfileHelper::GetSigninProfile()->GetRequestContext(); 120 } 121 122 } // namespace chromeos 123