Home | History | Annotate | Download | only in infobars
      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/ui/android/infobars/auto_login_prompter.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/command_line.h"
      9 #include "base/logging.h"
     10 #include "base/prefs/pref_service.h"
     11 #include "chrome/browser/profiles/profile.h"
     12 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
     13 #include "chrome/browser/signin/signin_manager_factory.h"
     14 #include "chrome/browser/tab_contents/tab_util.h"
     15 #include "chrome/common/chrome_switches.h"
     16 #include "chrome/common/pref_names.h"
     17 #include "components/auto_login_parser/auto_login_parser.h"
     18 #include "components/google/core/browser/google_url_tracker.h"
     19 #include "components/signin/core/browser/profile_oauth2_token_service.h"
     20 #include "components/signin/core/browser/signin_manager.h"
     21 #include "content/public/browser/browser_thread.h"
     22 #include "content/public/browser/web_contents.h"
     23 #include "net/url_request/url_request.h"
     24 #include "url/gurl.h"
     25 
     26 using content::BrowserThread;
     27 using content::BrowserContext;
     28 using content::WebContents;
     29 
     30 AutoLoginPrompter::AutoLoginPrompter(WebContents* web_contents,
     31                                      const Params& params,
     32                                      const GURL& url)
     33     : WebContentsObserver(web_contents),
     34       params_(params),
     35       url_(url),
     36       infobar_shown_(false) {
     37   if (!web_contents->IsLoading()) {
     38     // If the WebContents isn't loading a page, the load notification will never
     39     // be triggered.  Try adding the InfoBar now.
     40     AddInfoBarToWebContents();
     41   }
     42 }
     43 
     44 AutoLoginPrompter::~AutoLoginPrompter() {
     45 }
     46 
     47 // static
     48 void AutoLoginPrompter::ShowInfoBarIfPossible(net::URLRequest* request,
     49                                               int child_id,
     50                                               int route_id) {
     51   // See if the response contains the X-Auto-Login header.  If so, this was
     52   // a request for a login page, and the server is allowing the browser to
     53   // suggest auto-login, if available.
     54   Params params;
     55   // Currently we only accept GAIA credentials in Chrome.
     56   if (!auto_login_parser::ParserHeaderInResponse(
     57           request, auto_login_parser::ONLY_GOOGLE_COM, &params.header))
     58     return;
     59 
     60   BrowserThread::PostTask(
     61       BrowserThread::UI, FROM_HERE,
     62       base::Bind(&ShowInfoBarUIThread,
     63                  params, request->url(), child_id, route_id));
     64 }
     65 
     66 
     67 // static
     68 void AutoLoginPrompter::ShowInfoBarUIThread(Params params,
     69                                             const GURL& url,
     70                                             int child_id,
     71                                             int route_id) {
     72   DCHECK_CURRENTLY_ON(BrowserThread::UI);
     73   WebContents* web_contents = tab_util::GetWebContentsByID(child_id, route_id);
     74   if (!web_contents)
     75     return;
     76 
     77   BrowserContext* context = web_contents->GetBrowserContext();
     78   if (context->IsOffTheRecord())
     79     return;
     80 
     81   Profile* profile = Profile::FromBrowserContext(context);
     82   if (!profile->GetPrefs()->GetBoolean(prefs::kAutologinEnabled))
     83     return;
     84 
     85   // Make sure that |account|, if specified, matches the logged in user.
     86   // However, |account| is usually empty.
     87   if (!params.username.empty() && !params.header.account.empty() &&
     88       params.username != params.header.account)
     89     return;
     90   // We can't add the infobar just yet, since we need to wait for the tab to
     91   // finish loading.  If we don't, the info bar appears and then disappears
     92   // immediately.  Create an AutoLoginPrompter instance to listen for the
     93   // relevant notifications; it will delete itself.
     94   new AutoLoginPrompter(web_contents, params, url);
     95 }
     96 
     97 void AutoLoginPrompter::DidStopLoading(
     98     content::RenderViewHost* render_view_host) {
     99   AddInfoBarToWebContents();
    100   delete this;
    101 }
    102 
    103 void AutoLoginPrompter::WebContentsDestroyed() {
    104   // The WebContents was destroyed before the navigation completed.
    105   delete this;
    106 }
    107 
    108 void AutoLoginPrompter::AddInfoBarToWebContents() {
    109   if (!infobar_shown_)
    110     infobar_shown_ = AutoLoginInfoBarDelegate::Create(web_contents(), params_);
    111 }
    112