15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "android_webview/renderer/aw_content_renderer_client.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "android_webview/common/aw_resource.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "android_webview/common/render_view_messages.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "android_webview/common/url_constants.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "android_webview/renderer/aw_key_systems.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "android_webview/renderer/aw_render_view_ext.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "android_webview/renderer/print_web_view_helper.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/message_loop/message_loop.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "components/autofill/content/renderer/autofill_agent.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "components/autofill/content/renderer/password_autofill_agent.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "components/visitedlink/renderer/visitedlink_slave.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/url_constants.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/renderer/document_state.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/renderer/navigation_state.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/renderer/render_thread.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/renderer/render_view.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/escape.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebString.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURL.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLError.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLRequest.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/WebKit/public/web/WebFrame.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/WebKit/public/web/WebNavigationType.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/WebKit/public/web/WebSecurityPolicy.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "url/gurl.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderThread;
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace android_webview {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AwContentRendererClient::AwContentRendererClient() {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AwContentRendererClient::~AwContentRendererClient() {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AwContentRendererClient::RenderThreadStarted() {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  blink::WebString content_scheme(
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASCIIToUTF16(android_webview::kContentScheme));
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  blink::WebSecurityPolicy::registerURLSchemeAsLocal(content_scheme);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  blink::WebString aw_scheme(
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ASCIIToUTF16(android_webview::kAndroidWebViewVideoPosterScheme));
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  blink::WebSecurityPolicy::registerURLSchemeAsSecure(aw_scheme);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderThread* thread = RenderThread::Get();
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  aw_render_process_observer_.reset(new AwRenderProcessObserver);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  thread->AddObserver(aw_render_process_observer_.get());
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  visited_link_slave_.reset(new visitedlink::VisitedLinkSlave);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  thread->AddObserver(visited_link_slave_.get());
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AwContentRendererClient::HandleNavigation(
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::RenderView* view,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::DocumentState* document_state,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int opener_id,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    blink::WebFrame* frame,
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const blink::WebURLRequest& request,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    blink::WebNavigationType type,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    blink::WebNavigationPolicy default_policy,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_redirect) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Only GETs can be overridden.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!request.httpMethod().equals("GET"))
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Any navigation from loadUrl, and goBack/Forward are considered application-
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // initiated and hence will not yield a shouldOverrideUrlLoading() callback.
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Webview classic does not consider reload application-initiated so we
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // continue the same behavior.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(sgurun) is_content_initiated is normally false for cross-origin
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // navigations but since android_webview does not swap out renderers, this
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // works fine. This will stop working if android_webview starts swapping out
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // renderers on navigation.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool application_initiated =
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !document_state->navigation_state()->is_content_initiated()
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      || type == blink::WebNavigationTypeBackForward;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Don't offer application-initiated navigations unless it's a redirect.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (application_initiated && !is_redirect)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL& gurl = request.url();
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For HTTP schemes, only top-level navigations can be overridden. Similarly,
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // WebView Classic lets app override only top level about:blank navigations.
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // So we filter out non-top about:blank navigations here.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (frame->parent() && (gurl.SchemeIs(content::kHttpScheme) ||
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          gurl.SchemeIs(content::kHttpsScheme) ||
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          gurl.SchemeIs(chrome::kAboutScheme)))
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // use NavigationInterception throttle to handle the call as that can
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be deferred until after the java side has been constructed.
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (opener_id != MSG_ROUTING_NONE) {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ignore_navigation = false;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::string16 url =  request.url().string();
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int routing_id = view->GetRoutingID();
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderThread::Get()->Send(new AwViewHostMsg_ShouldOverrideUrlLoading(
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      routing_id, url, &ignore_navigation));
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ignore_navigation;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AwContentRendererClient::RenderViewCreated(
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::RenderView* render_view) {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AwRenderViewExt::RenderViewCreated(render_view);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new printing::PrintWebViewHelper(render_view);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(sgurun) do not create a password autofill agent (change
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // autofill agent to store a weakptr).
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  autofill::PasswordAutofillAgent* password_autofill_agent =
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new autofill::PasswordAutofillAgent(render_view);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new autofill::AutofillAgent(render_view, password_autofill_agent);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string AwContentRendererClient::GetDefaultEncoding() {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return AwResource::GetDefaultTextEncoding();
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AwContentRendererClient::HasErrorPage(int http_status_code,
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          std::string* error_domain) {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return http_status_code >= 400;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AwContentRendererClient::GetNavigationErrorStrings(
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    blink::WebFrame* /* frame */,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const blink::WebURLRequest& failed_request,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const blink::WebURLError& error,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& accept_languages,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string* error_html,
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    string16* error_description) {
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (error_html) {
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GURL error_url(failed_request.url());
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string err = UTF16ToUTF8(error.localizedDescription);
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string contents;
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (err.empty()) {
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      contents = AwResource::GetNoDomainPageContent();
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents = AwResource::GetLoadErrorPageContent();
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ReplaceSubstringsAfterOffset(&contents, 0, "%e", err);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReplaceSubstringsAfterOffset(&contents, 0, "%s",
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        net::EscapeForHTML(error_url.possibly_invalid_spec()));
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error_html = contents;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (error_description) {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (error.localizedDescription.isEmpty())
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *error_description = ASCIIToUTF16(net::ErrorToString(error.reason));
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *error_description = error.localizedDescription;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)unsigned long long AwContentRendererClient::VisitedLinkHash(
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* canonical_url,
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t length) {
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return visited_link_slave_->ComputeURLFingerprint(canonical_url, length);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AwContentRendererClient::IsLinkVisited(unsigned long long link_hash) {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return visited_link_slave_->IsVisited(link_hash);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AwContentRendererClient::AddKeySystems(
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::vector<content::KeySystemInfo>* key_systems) {
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AwAddKeySystems(key_systems);
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace android_webview
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)