Home | History | Annotate | Download | only in signin
      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/signin/merge_session_load_page.h"
      6 
      7 #include "ash/shell.h"
      8 #include "ash/shell_delegate.h"
      9 #include "ash/system/tray/system_tray_delegate.h"
     10 #include "base/i18n/rtl.h"
     11 #include "base/metrics/histogram.h"
     12 #include "base/strings/string_piece.h"
     13 #include "base/strings/stringprintf.h"
     14 #include "base/strings/utf_string_conversions.h"
     15 #include "base/values.h"
     16 #include "chrome/browser/chrome_notification_types.h"
     17 #include "chrome/browser/chromeos/login/signin/oauth2_login_manager_factory.h"
     18 #include "chrome/browser/extensions/extension_service.h"
     19 #include "chrome/browser/profiles/profile.h"
     20 #include "chrome/browser/renderer_preferences_util.h"
     21 #include "chrome/browser/tab_contents/tab_util.h"
     22 #include "chrome/common/extensions/extension_constants.h"
     23 #include "chrome/common/url_constants.h"
     24 #include "content/public/browser/browser_thread.h"
     25 #include "content/public/browser/interstitial_page.h"
     26 #include "content/public/browser/notification_types.h"
     27 #include "content/public/browser/web_contents.h"
     28 #include "extensions/browser/extension_system.h"
     29 #include "extensions/common/extension.h"
     30 #include "extensions/common/extension_icon_set.h"
     31 #include "grit/browser_resources.h"
     32 #include "grit/generated_resources.h"
     33 #include "net/base/escape.h"
     34 #include "ui/base/l10n/l10n_util.h"
     35 #include "ui/base/resource/resource_bundle.h"
     36 #include "ui/base/webui/jstemplate_builder.h"
     37 
     38 using content::BrowserThread;
     39 using content::InterstitialPage;
     40 using content::WebContents;
     41 
     42 namespace {
     43 
     44 // Delay time for showing interstitial page.
     45 const int kShowDelayTimeMS = 1000;
     46 
     47 // Maximum time for showing interstitial page.
     48 const int kTotalWaitTimeMS = 10000;
     49 
     50 }  // namespace
     51 
     52 namespace chromeos {
     53 
     54 MergeSessionLoadPage::MergeSessionLoadPage(
     55     WebContents* web_contents,
     56     const GURL& url,
     57     const MergeSessionThrottle::CompletionCallback& callback)
     58     : callback_(callback),
     59       proceeded_(false),
     60       web_contents_(web_contents),
     61       url_(url) {
     62   interstitial_page_ = InterstitialPage::Create(web_contents, true, url, this);
     63 }
     64 
     65 MergeSessionLoadPage::~MergeSessionLoadPage() {
     66   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     67 }
     68 
     69 void MergeSessionLoadPage::Show() {
     70   OAuth2LoginManager* manager = GetOAuth2LoginManager();
     71   if (manager && manager->ShouldBlockTabLoading()) {
     72     manager->AddObserver(this);
     73     interstitial_page_->Show();
     74   } else {
     75     interstitial_page_->Proceed();
     76   }
     77 }
     78 
     79 std::string MergeSessionLoadPage::GetHTMLContents() {
     80   base::DictionaryValue strings;
     81   strings.SetString("title", web_contents_->GetTitle());
     82   // Set the timeout to show the page.
     83   strings.SetInteger("show_delay_time", kShowDelayTimeMS);
     84   strings.SetInteger("total_wait_time", kTotalWaitTimeMS);
     85   // TODO(zelidrag): Flip the message to IDS_MERGE_SESSION_LOAD_HEADLINE
     86   // after merge.
     87   strings.SetString("heading",
     88                     l10n_util::GetStringUTF16(IDS_TAB_LOADING_TITLE));
     89 
     90   bool rtl = base::i18n::IsRTL();
     91   strings.SetString("textdirection", rtl ? "rtl" : "ltr");
     92 
     93   base::StringPiece html(
     94       ResourceBundle::GetSharedInstance().GetRawDataResource(
     95           IDR_MERGE_SESSION_LOAD_HTML));
     96   return webui::GetI18nTemplateHtml(html, &strings);
     97 }
     98 
     99 void MergeSessionLoadPage::OverrideRendererPrefs(
    100       content::RendererPreferences* prefs) {
    101   Profile* profile = Profile::FromBrowserContext(
    102       web_contents_->GetBrowserContext());
    103   renderer_preferences_util::UpdateFromSystemSettings(prefs, profile);
    104 }
    105 
    106 void MergeSessionLoadPage::OnProceed() {
    107   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    108   proceeded_ = true;
    109   NotifyBlockingPageComplete();
    110 }
    111 
    112 void MergeSessionLoadPage::OnDontProceed() {
    113   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    114   // Ignore if it's already proceeded.
    115   if (proceeded_)
    116     return;
    117   NotifyBlockingPageComplete();
    118 }
    119 
    120 void MergeSessionLoadPage::CommandReceived(const std::string& cmd) {
    121   std::string command(cmd);
    122   // The Jasonified response has quotes, remove them.
    123   if (command.length() > 1 && command[0] == '"')
    124     command = command.substr(1, command.length() - 2);
    125 
    126   if (command == "proceed") {
    127     interstitial_page_->Proceed();
    128   } else {
    129     DVLOG(1) << "Unknown command:" << cmd;
    130   }
    131 }
    132 
    133 void MergeSessionLoadPage::NotifyBlockingPageComplete() {
    134   OAuth2LoginManager* manager = GetOAuth2LoginManager();
    135   if (manager)
    136     manager->RemoveObserver(this);
    137 
    138   if (!callback_.is_null()) {
    139     BrowserThread::PostTask(
    140         BrowserThread::IO, FROM_HERE, callback_);
    141   }
    142 }
    143 
    144 OAuth2LoginManager* MergeSessionLoadPage::GetOAuth2LoginManager() {
    145   content::BrowserContext* browser_context = web_contents_->GetBrowserContext();
    146   if (!browser_context)
    147     return NULL;
    148 
    149   Profile* profile = Profile::FromBrowserContext(browser_context);
    150   if (!profile)
    151     return NULL;
    152 
    153   return OAuth2LoginManagerFactory::GetInstance()->GetForProfile(profile);
    154 }
    155 
    156 void MergeSessionLoadPage::OnSessionRestoreStateChanged(
    157     Profile* user_profile, OAuth2LoginManager::SessionRestoreState state) {
    158   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    159 
    160   OAuth2LoginManager* manager = GetOAuth2LoginManager();
    161   DVLOG(1) << "Merge session should "
    162            << (!manager->ShouldBlockTabLoading() ?
    163                   " NOT " : "")
    164            << " be blocking now, "
    165            << state;
    166   if (!manager->ShouldBlockTabLoading()) {
    167     manager->RemoveObserver(this);
    168     interstitial_page_->Proceed();
    169   }
    170 }
    171 
    172 }  // namespace chromeos
    173