Home | History | Annotate | Download | only in offline
      1 // Copyright (c) 2012 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/offline/offline_load_page.h"
      6 
      7 #include "apps/launcher.h"
      8 #include "ash/shell.h"
      9 #include "ash/shell_delegate.h"
     10 #include "ash/system/tray/system_tray_delegate.h"
     11 #include "base/i18n/rtl.h"
     12 #include "base/metrics/histogram.h"
     13 #include "base/prefs/pref_service.h"
     14 #include "base/strings/string_piece.h"
     15 #include "base/strings/stringprintf.h"
     16 #include "base/strings/utf_string_conversions.h"
     17 #include "base/values.h"
     18 #include "chrome/browser/browser_process.h"
     19 #include "chrome/browser/chrome_notification_types.h"
     20 #include "chrome/browser/profiles/profile.h"
     21 #include "chrome/browser/renderer_preferences_util.h"
     22 #include "chrome/browser/tab_contents/tab_util.h"
     23 #include "chrome/common/extensions/extension_constants.h"
     24 #include "chrome/common/localized_error.h"
     25 #include "chrome/common/pref_names.h"
     26 #include "chrome/common/url_constants.h"
     27 #include "chrome/grit/browser_resources.h"
     28 #include "content/public/browser/browser_thread.h"
     29 #include "content/public/browser/interstitial_page.h"
     30 #include "content/public/browser/notification_types.h"
     31 #include "content/public/browser/web_contents.h"
     32 #include "extensions/browser/extension_registry.h"
     33 #include "extensions/browser/extension_system.h"
     34 #include "extensions/common/extension.h"
     35 #include "extensions/common/extension_icon_set.h"
     36 #include "extensions/common/manifest_handlers/icons_handler.h"
     37 #include "net/base/escape.h"
     38 #include "net/base/net_errors.h"
     39 #include "ui/base/resource/resource_bundle.h"
     40 #include "ui/base/webui/jstemplate_builder.h"
     41 #include "ui/base/webui/web_ui_util.h"
     42 
     43 using content::BrowserThread;
     44 using content::InterstitialPage;
     45 using content::WebContents;
     46 
     47 namespace chromeos {
     48 
     49 OfflineLoadPage::OfflineLoadPage(WebContents* web_contents,
     50                                  const GURL& url,
     51                                  const CompletionCallback& callback)
     52     : callback_(callback),
     53       proceeded_(false),
     54       web_contents_(web_contents),
     55       url_(url) {
     56   net::NetworkChangeNotifier::AddConnectionTypeObserver(this);
     57   interstitial_page_ = InterstitialPage::Create(web_contents, true, url, this);
     58 }
     59 
     60 OfflineLoadPage::~OfflineLoadPage() {
     61   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     62   net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
     63 }
     64 
     65 void OfflineLoadPage::Show() {
     66   interstitial_page_->Show();
     67 }
     68 
     69 std::string OfflineLoadPage::GetHTMLContents() {
     70   // Use a local error page.
     71   int resource_id;
     72   base::DictionaryValue error_strings;
     73 
     74   // The offline page for app has icons and slightly different message.
     75   Profile* profile = Profile::FromBrowserContext(
     76       web_contents_->GetBrowserContext());
     77   DCHECK(profile);
     78   const extensions::Extension* extension = extensions::ExtensionRegistry::Get(
     79       profile)->enabled_extensions().GetHostedAppByURL(url_);
     80   if (extension && !extension->from_bookmark()) {
     81     LocalizedError::GetAppErrorStrings(url_, extension, &error_strings);
     82     resource_id = IDR_OFFLINE_APP_LOAD_HTML;
     83   } else {
     84     const std::string locale = g_browser_process->GetApplicationLocale();
     85     const std::string accept_languages =
     86         profile->GetPrefs()->GetString(prefs::kAcceptLanguages);
     87     LocalizedError::GetStrings(net::ERR_INTERNET_DISCONNECTED,
     88                                net::kErrorDomain, url_, false, false, locale,
     89                                accept_languages,
     90                                scoped_ptr<LocalizedError::ErrorPageParams>(),
     91                                &error_strings);
     92     resource_id = IDR_OFFLINE_NET_LOAD_HTML;
     93   }
     94 
     95   const base::StringPiece template_html(
     96       ResourceBundle::GetSharedInstance().GetRawDataResource(
     97           resource_id));
     98   // "t" is the id of the templates root node.
     99   return webui::GetTemplatesHtml(template_html, &error_strings, "t");
    100 }
    101 
    102 void OfflineLoadPage::OverrideRendererPrefs(
    103     content::RendererPreferences* prefs) {
    104   Profile* profile = Profile::FromBrowserContext(
    105       web_contents_->GetBrowserContext());
    106   renderer_preferences_util::UpdateFromSystemSettings(prefs, profile);
    107 }
    108 
    109 void OfflineLoadPage::OnProceed() {
    110   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    111   proceeded_ = true;
    112   NotifyBlockingPageComplete(true);
    113 }
    114 
    115 void OfflineLoadPage::OnDontProceed() {
    116   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    117   // Ignore if it's already proceeded.
    118   if (proceeded_)
    119     return;
    120   NotifyBlockingPageComplete(false);
    121 }
    122 
    123 void OfflineLoadPage::CommandReceived(const std::string& cmd) {
    124   std::string command(cmd);
    125   // The Jasonified response has quotes, remove them.
    126   if (command.length() > 1 && command[0] == '"') {
    127     command = command.substr(1, command.length() - 2);
    128   }
    129   // TODO(oshima): record action for metrics.
    130   if (command == "open_network_settings") {
    131     ash::Shell::GetInstance()->system_tray_delegate()->ShowNetworkSettings("");
    132   } else if (command == "open_connectivity_diagnostics") {
    133     Profile* profile = Profile::FromBrowserContext(
    134         web_contents_->GetBrowserContext());
    135     const extensions::Extension* extension =
    136         extensions::ExtensionRegistry::Get(profile)->GetExtensionById(
    137             "kodldpbjkkmmnilagfdheibampofhaom",
    138             extensions::ExtensionRegistry::EVERYTHING);
    139     apps::LaunchPlatformAppWithUrl(profile, extension, "",
    140                                    GURL::EmptyGURL(), GURL::EmptyGURL());
    141 
    142   } else {
    143     LOG(WARNING) << "Unknown command:" << cmd;
    144   }
    145 }
    146 
    147 void OfflineLoadPage::NotifyBlockingPageComplete(bool proceed) {
    148   BrowserThread::PostTask(
    149       BrowserThread::IO, FROM_HERE, base::Bind(callback_, proceed));
    150 }
    151 
    152 void OfflineLoadPage::OnConnectionTypeChanged(
    153     net::NetworkChangeNotifier::ConnectionType type) {
    154   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    155   const bool online = type != net::NetworkChangeNotifier::CONNECTION_NONE;
    156   DVLOG(1) << "ConnectionTypeObserver notification received: state="
    157            << (online ? "online" : "offline");
    158   if (online) {
    159     net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
    160     interstitial_page_->Proceed();
    161   }
    162 }
    163 
    164 }  // namespace chromeos
    165