Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / renderer / net / net_error_helper.cc
index 2c16add..b1854d0 100644 (file)
@@ -6,20 +6,26 @@
 
 #include <string>
 
+#include "base/command_line.h"
+#include "base/i18n/rtl.h"
 #include "base/json/json_writer.h"
 #include "base/metrics/histogram.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
+#include "chrome/common/chrome_switches.h"
 #include "chrome/common/localized_error.h"
 #include "chrome/common/net/net_error_info.h"
 #include "chrome/common/render_messages.h"
+#include "chrome/grit/renderer_resources.h"
+#include "chrome/renderer/net/net_error_page_controller.h"
 #include "content/public/common/content_client.h"
 #include "content/public/common/url_constants.h"
 #include "content/public/renderer/content_renderer_client.h"
+#include "content/public/renderer/document_state.h"
+#include "content/public/renderer/render_frame.h"
 #include "content/public/renderer/render_thread.h"
 #include "content/public/renderer/render_view.h"
 #include "content/public/renderer/resource_fetcher.h"
-#include "grit/renderer_resources.h"
 #include "ipc/ipc_message.h"
 #include "ipc/ipc_message_macros.h"
 #include "third_party/WebKit/public/platform/WebURL.h"
@@ -27,6 +33,7 @@
 #include "third_party/WebKit/public/platform/WebURLRequest.h"
 #include "third_party/WebKit/public/platform/WebURLResponse.h"
 #include "third_party/WebKit/public/web/WebDataSource.h"
+#include "third_party/WebKit/public/web/WebDocument.h"
 #include "third_party/WebKit/public/web/WebFrame.h"
 #include "third_party/WebKit/public/web/WebView.h"
 #include "ui/base/resource/resource_bundle.h"
 using base::JSONWriter;
 using chrome_common_net::DnsProbeStatus;
 using chrome_common_net::DnsProbeStatusToString;
+using content::DocumentState;
+using content::RenderFrame;
+using content::RenderFrameObserver;
 using content::RenderThread;
-using content::RenderView;
-using content::RenderViewObserver;
 using content::kUnreachableWebDataURL;
 
 namespace {
 
-// Number of seconds to wait for the alternate error page server.  If it takes
-// too long, just use the local error page.
-static const int kAlterErrorPageFetchTimeoutSec = 3000;
+// Number of seconds to wait for the navigation correction service to return
+// suggestions.  If it takes too long, just use the local error page.
+static const int kNavigationCorrectionFetchTimeoutSec = 3;
 
 NetErrorHelperCore::PageType GetLoadingPageType(const blink::WebFrame* frame) {
   GURL url = frame->provisionalDataSource()->request().url();
@@ -62,30 +70,62 @@ NetErrorHelperCore::FrameType GetFrameType(const blink::WebFrame* frame) {
 
 }  // namespace
 
-NetErrorHelper::NetErrorHelper(RenderView* render_view)
-    : RenderViewObserver(render_view),
-      content::RenderViewObserverTracker<NetErrorHelper>(render_view),
-      core_(this) {
+NetErrorHelper::NetErrorHelper(RenderFrame* render_frame)
+    : RenderFrameObserver(render_frame),
+      content::RenderFrameObserverTracker<NetErrorHelper>(render_frame) {
+  RenderThread::Get()->AddObserver(this);
+  CommandLine* command_line = CommandLine::ForCurrentProcess();
+  bool auto_reload_enabled =
+      command_line->HasSwitch(switches::kEnableOfflineAutoReload);
+  bool auto_reload_visible_only =
+      command_line->HasSwitch(switches::kEnableOfflineAutoReloadVisibleOnly);
+  core_.reset(new NetErrorHelperCore(this,
+                                     auto_reload_enabled,
+                                     auto_reload_visible_only,
+                                     !render_frame->IsHidden()));
 }
 
 NetErrorHelper::~NetErrorHelper() {
+  RenderThread::Get()->RemoveObserver(this);
 }
 
-void NetErrorHelper::DidStartProvisionalLoad(blink::WebFrame* frame) {
-  core_.OnStartLoad(GetFrameType(frame), GetLoadingPageType(frame));
+void NetErrorHelper::ReloadButtonPressed() {
+  core_->ExecuteButtonPress(NetErrorHelperCore::RELOAD_BUTTON);
 }
 
-void NetErrorHelper::DidCommitProvisionalLoad(blink::WebFrame* frame,
-                                              bool is_new_navigation) {
-  core_.OnCommitLoad(GetFrameType(frame));
+void NetErrorHelper::LoadStaleButtonPressed() {
+  core_->ExecuteButtonPress(NetErrorHelperCore::LOAD_STALE_BUTTON);
 }
 
-void NetErrorHelper::DidFinishLoad(blink::WebFrame* frame) {
-  core_.OnFinishLoad(GetFrameType(frame));
+void NetErrorHelper::MoreButtonPressed() {
+  core_->ExecuteButtonPress(NetErrorHelperCore::MORE_BUTTON);
+}
+
+void NetErrorHelper::DidStartProvisionalLoad() {
+  blink::WebFrame* frame = render_frame()->GetWebFrame();
+  core_->OnStartLoad(GetFrameType(frame), GetLoadingPageType(frame));
+}
+
+void NetErrorHelper::DidCommitProvisionalLoad(bool is_new_navigation) {
+  blink::WebFrame* frame = render_frame()->GetWebFrame();
+  core_->OnCommitLoad(GetFrameType(frame), frame->document().url());
+}
+
+void NetErrorHelper::DidFinishLoad() {
+  blink::WebFrame* frame = render_frame()->GetWebFrame();
+  core_->OnFinishLoad(GetFrameType(frame));
 }
 
 void NetErrorHelper::OnStop() {
-  core_.OnStop();
+  core_->OnStop();
+}
+
+void NetErrorHelper::WasShown() {
+  core_->OnWasShown();
+}
+
+void NetErrorHelper::WasHidden() {
+  core_->OnWasHidden();
 }
 
 bool NetErrorHelper::OnMessageReceived(const IPC::Message& message) {
@@ -93,24 +133,42 @@ bool NetErrorHelper::OnMessageReceived(const IPC::Message& message) {
 
   IPC_BEGIN_MESSAGE_MAP(NetErrorHelper, message)
     IPC_MESSAGE_HANDLER(ChromeViewMsg_NetErrorInfo, OnNetErrorInfo)
-    IPC_MESSAGE_HANDLER(ChromeViewMsg_SetAltErrorPageURL, OnSetAltErrorPageURL);
+    IPC_MESSAGE_HANDLER(ChromeViewMsg_SetNavigationCorrectionInfo,
+                        OnSetNavigationCorrectionInfo);
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
 
   return handled;
 }
 
+void NetErrorHelper::NetworkStateChanged(bool enabled) {
+  core_->NetworkStateChanged(enabled);
+}
+
 void NetErrorHelper::GetErrorHTML(
     blink::WebFrame* frame,
     const blink::WebURLError& error,
     bool is_failed_post,
     std::string* error_html) {
-  core_.GetErrorHTML(GetFrameType(frame), error, is_failed_post, error_html);
+  core_->GetErrorHTML(GetFrameType(frame), error, is_failed_post, error_html);
+}
+
+bool NetErrorHelper::ShouldSuppressErrorPage(blink::WebFrame* frame,
+                                             const GURL& url) {
+  return core_->ShouldSuppressErrorPage(GetFrameType(frame), url);
+}
+
+void NetErrorHelper::TrackClick(int tracking_id) {
+  core_->TrackClick(tracking_id);
 }
 
-void NetErrorHelper::GenerateLocalizedErrorPage(const blink::WebURLError& error,
-                                                bool is_failed_post,
-                                                std::string* error_html) const {
+void NetErrorHelper::GenerateLocalizedErrorPage(
+    const blink::WebURLError& error,
+    bool is_failed_post,
+    scoped_ptr<LocalizedError::ErrorPageParams> params,
+    bool* reload_button_shown,
+    bool* load_stale_button_shown,
+    std::string* error_html) const {
   error_html->clear();
 
   int resource_id = IDR_NET_ERROR_HTML;
@@ -119,12 +177,22 @@ void NetErrorHelper::GenerateLocalizedErrorPage(const blink::WebURLError& error,
   if (template_html.empty()) {
     NOTREACHED() << "unable to load template.";
   } else {
+    CommandLine* command_line = CommandLine::ForCurrentProcess();
+    bool load_stale_cache_enabled =
+        command_line->HasSwitch(switches::kEnableOfflineLoadStaleCache);
+
     base::DictionaryValue error_strings;
     LocalizedError::GetStrings(error.reason, error.domain.utf8(),
                                error.unreachableURL, is_failed_post,
+                               (load_stale_cache_enabled &&
+                                error.staleCopyInCache && !is_failed_post),
                                RenderThread::Get()->GetLocale(),
-                               render_view()->GetAcceptLanguages(),
-                               &error_strings);
+                               render_frame()->GetRenderView()->
+                                   GetAcceptLanguages(),
+                               params.Pass(), &error_strings);
+    *reload_button_shown = error_strings.Get("reloadButton", NULL);
+    *load_stale_button_shown = error_strings.Get("staleLoadButton", NULL);
+
     // "t" is the id of the template's root node.
     *error_html = webui::GetTemplatesHtml(template_html, &error_strings, "t");
   }
@@ -132,22 +200,34 @@ void NetErrorHelper::GenerateLocalizedErrorPage(const blink::WebURLError& error,
 
 void NetErrorHelper::LoadErrorPageInMainFrame(const std::string& html,
                                               const GURL& failed_url) {
-  blink::WebView* web_view = render_view()->GetWebView();
+  blink::WebView* web_view = render_frame()->GetRenderView()->GetWebView();
   if (!web_view)
     return;
   blink::WebFrame* frame = web_view->mainFrame();
   frame->loadHTMLString(html, GURL(kUnreachableWebDataURL), failed_url, true);
 }
 
+void NetErrorHelper::EnablePageHelperFunctions() {
+  NetErrorPageController::Install(render_frame());
+}
+
 void NetErrorHelper::UpdateErrorPage(const blink::WebURLError& error,
                                      bool is_failed_post) {
+    CommandLine* command_line = CommandLine::ForCurrentProcess();
+    bool load_stale_cache_enabled =
+        command_line->HasSwitch(switches::kEnableOfflineLoadStaleCache);
+
   base::DictionaryValue error_strings;
   LocalizedError::GetStrings(error.reason,
                              error.domain.utf8(),
                              error.unreachableURL,
                              is_failed_post,
+                             (load_stale_cache_enabled &&
+                              error.staleCopyInCache && !is_failed_post),
                              RenderThread::Get()->GetLocale(),
-                             render_view()->GetAcceptLanguages(),
+                             render_frame()->GetRenderView()->
+                                 GetAcceptLanguages(),
+                             scoped_ptr<LocalizedError::ErrorPageParams>(),
                              &error_strings);
 
   std::string json;
@@ -161,30 +241,74 @@ void NetErrorHelper::UpdateErrorPage(const blink::WebURLError& error,
     return;
   }
 
-  base::string16 frame_xpath;
-  render_view()->EvaluateScript(frame_xpath, js16, 0, false);
+  render_frame()->ExecuteJavaScript(js16);
+}
+
+void NetErrorHelper::FetchNavigationCorrections(
+    const GURL& navigation_correction_url,
+    const std::string& navigation_correction_request_body) {
+  DCHECK(!correction_fetcher_.get());
+
+  blink::WebView* web_view = render_frame()->GetRenderView()->GetWebView();
+  if (!web_view)
+    return;
+  blink::WebFrame* frame = web_view->mainFrame();
+
+  correction_fetcher_.reset(
+      content::ResourceFetcher::Create(navigation_correction_url));
+  correction_fetcher_->SetMethod("POST");
+  correction_fetcher_->SetBody(navigation_correction_request_body);
+  correction_fetcher_->SetHeader("Content-Type", "application/json");
+
+  correction_fetcher_->Start(
+      frame,
+      blink::WebURLRequest::RequestContextInternal,
+      blink::WebURLRequest::FrameTypeTopLevel,
+      base::Bind(&NetErrorHelper::OnNavigationCorrectionsFetched,
+                 base::Unretained(this)));
+
+  correction_fetcher_->SetTimeout(
+      base::TimeDelta::FromSeconds(kNavigationCorrectionFetchTimeoutSec));
 }
 
-void NetErrorHelper::FetchErrorPage(const GURL& url) {
-  DCHECK(!alt_error_page_fetcher_.get());
+void NetErrorHelper::CancelFetchNavigationCorrections() {
+  correction_fetcher_.reset();
+}
 
-  blink::WebView* web_view = render_view()->GetWebView();
+void NetErrorHelper::SendTrackingRequest(
+    const GURL& tracking_url,
+    const std::string& tracking_request_body) {
+  blink::WebView* web_view = render_frame()->GetRenderView()->GetWebView();
   if (!web_view)
     return;
   blink::WebFrame* frame = web_view->mainFrame();
 
-  alt_error_page_fetcher_.reset(
-      content::ResourceFetcher::Create(
-          url, frame, blink::WebURLRequest::TargetIsMainFrame,
-          base::Bind(&NetErrorHelper::OnAlternateErrorPageRetrieved,
-                     base::Unretained(this))));
+  // If there's already a pending tracking request, this will cancel it.
+  tracking_fetcher_.reset(content::ResourceFetcher::Create(tracking_url));
+  tracking_fetcher_->SetMethod("POST");
+  tracking_fetcher_->SetBody(tracking_request_body);
+  tracking_fetcher_->SetHeader("Content-Type", "application/json");
+
+  tracking_fetcher_->Start(
+      frame,
+      blink::WebURLRequest::RequestContextInternal,
+      blink::WebURLRequest::FrameTypeTopLevel,
+      base::Bind(&NetErrorHelper::OnTrackingRequestComplete,
+                 base::Unretained(this)));
+}
 
-  alt_error_page_fetcher_->SetTimeout(
-      base::TimeDelta::FromSeconds(kAlterErrorPageFetchTimeoutSec));
+void NetErrorHelper::ReloadPage() {
+  render_frame()->GetWebFrame()->reload(false);
 }
 
-void NetErrorHelper::CancelFetchErrorPage() {
-  alt_error_page_fetcher_.reset();
+void NetErrorHelper::LoadPageFromCache(const GURL& page_url) {
+  blink::WebFrame* web_frame = render_frame()->GetWebFrame();
+  DCHECK(!EqualsASCII(web_frame->dataSource()->request().httpMethod(), "POST"));
+
+  blink::WebURLRequest request(page_url);
+  request.setCachePolicy(blink::WebURLRequest::ReturnCacheDataDontLoad);
+
+  web_frame->loadRequest(request);
 }
 
 void NetErrorHelper::OnNetErrorInfo(int status_num) {
@@ -192,23 +316,35 @@ void NetErrorHelper::OnNetErrorInfo(int status_num) {
 
   DVLOG(1) << "Received status " << DnsProbeStatusToString(status_num);
 
-  core_.OnNetErrorInfo(static_cast<DnsProbeStatus>(status_num));
+  core_->OnNetErrorInfo(static_cast<DnsProbeStatus>(status_num));
 }
 
-void NetErrorHelper::OnSetAltErrorPageURL(const GURL& alt_error_page_url) {
-  core_.set_alt_error_page_url(alt_error_page_url);
+void NetErrorHelper::OnSetNavigationCorrectionInfo(
+    const GURL& navigation_correction_url,
+    const std::string& language,
+    const std::string& country_code,
+    const std::string& api_key,
+    const GURL& search_url) {
+  core_->OnSetNavigationCorrectionInfo(navigation_correction_url, language,
+                                      country_code, api_key, search_url);
 }
 
-void NetErrorHelper::OnAlternateErrorPageRetrieved(
+void NetErrorHelper::OnNavigationCorrectionsFetched(
     const blink::WebURLResponse& response,
     const std::string& data) {
   // The fetcher may only be deleted after |data| is passed to |core_|.  Move
   // it to a temporary to prevent any potential re-entrancy issues.
   scoped_ptr<content::ResourceFetcher> fetcher(
-      alt_error_page_fetcher_.release());
-  if (!response.isNull() && response.httpStatusCode() == 200) {
-    core_.OnAlternateErrorPageFetched(data);
-  } else {
-    core_.OnAlternateErrorPageFetched("");
-  }
+      correction_fetcher_.release());
+  bool success = (!response.isNull() && response.httpStatusCode() == 200);
+  core_->OnNavigationCorrectionsFetched(
+      success ? data : "",
+      render_frame()->GetRenderView()->GetAcceptLanguages(),
+      base::i18n::IsRTL());
+}
+
+void NetErrorHelper::OnTrackingRequestComplete(
+    const blink::WebURLResponse& response,
+    const std::string& data) {
+  tracking_fetcher_.reset();
 }