Home | History | Annotate | Download | only in auth
      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 
     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