1 // Copyright 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 "android_webview/renderer/aw_content_renderer_client.h" 6 7 #include "android_webview/common/aw_resource.h" 8 #include "android_webview/common/render_view_messages.h" 9 #include "android_webview/common/url_constants.h" 10 #include "android_webview/renderer/aw_key_systems.h" 11 #include "android_webview/renderer/aw_render_view_ext.h" 12 #include "android_webview/renderer/print_web_view_helper.h" 13 #include "base/message_loop/message_loop.h" 14 #include "base/strings/utf_string_conversions.h" 15 #include "components/autofill/content/renderer/autofill_agent.h" 16 #include "components/autofill/content/renderer/password_autofill_agent.h" 17 #include "components/visitedlink/renderer/visitedlink_slave.h" 18 #include "content/public/common/url_constants.h" 19 #include "content/public/renderer/document_state.h" 20 #include "content/public/renderer/navigation_state.h" 21 #include "content/public/renderer/render_thread.h" 22 #include "content/public/renderer/render_view.h" 23 #include "net/base/escape.h" 24 #include "net/base/net_errors.h" 25 #include "third_party/WebKit/public/platform/WebString.h" 26 #include "third_party/WebKit/public/platform/WebURL.h" 27 #include "third_party/WebKit/public/platform/WebURLError.h" 28 #include "third_party/WebKit/public/platform/WebURLRequest.h" 29 #include "third_party/WebKit/public/web/WebFrame.h" 30 #include "third_party/WebKit/public/web/WebNavigationType.h" 31 #include "third_party/WebKit/public/web/WebSecurityPolicy.h" 32 #include "url/gurl.h" 33 34 using content::RenderThread; 35 36 namespace android_webview { 37 38 AwContentRendererClient::AwContentRendererClient() { 39 } 40 41 AwContentRendererClient::~AwContentRendererClient() { 42 } 43 44 void AwContentRendererClient::RenderThreadStarted() { 45 blink::WebString content_scheme( 46 ASCIIToUTF16(android_webview::kContentScheme)); 47 blink::WebSecurityPolicy::registerURLSchemeAsLocal(content_scheme); 48 49 blink::WebString aw_scheme( 50 ASCIIToUTF16(android_webview::kAndroidWebViewVideoPosterScheme)); 51 blink::WebSecurityPolicy::registerURLSchemeAsSecure(aw_scheme); 52 53 RenderThread* thread = RenderThread::Get(); 54 55 aw_render_process_observer_.reset(new AwRenderProcessObserver); 56 thread->AddObserver(aw_render_process_observer_.get()); 57 58 visited_link_slave_.reset(new visitedlink::VisitedLinkSlave); 59 thread->AddObserver(visited_link_slave_.get()); 60 } 61 62 bool AwContentRendererClient::HandleNavigation( 63 content::RenderView* view, 64 content::DocumentState* document_state, 65 int opener_id, 66 blink::WebFrame* frame, 67 const blink::WebURLRequest& request, 68 blink::WebNavigationType type, 69 blink::WebNavigationPolicy default_policy, 70 bool is_redirect) { 71 72 // Only GETs can be overridden. 73 if (!request.httpMethod().equals("GET")) 74 return false; 75 76 // Any navigation from loadUrl, and goBack/Forward are considered application- 77 // initiated and hence will not yield a shouldOverrideUrlLoading() callback. 78 // Webview classic does not consider reload application-initiated so we 79 // continue the same behavior. 80 // TODO(sgurun) is_content_initiated is normally false for cross-origin 81 // navigations but since android_webview does not swap out renderers, this 82 // works fine. This will stop working if android_webview starts swapping out 83 // renderers on navigation. 84 bool application_initiated = 85 !document_state->navigation_state()->is_content_initiated() 86 || type == blink::WebNavigationTypeBackForward; 87 88 // Don't offer application-initiated navigations unless it's a redirect. 89 if (application_initiated && !is_redirect) 90 return false; 91 92 const GURL& gurl = request.url(); 93 // For HTTP schemes, only top-level navigations can be overridden. Similarly, 94 // WebView Classic lets app override only top level about:blank navigations. 95 // So we filter out non-top about:blank navigations here. 96 if (frame->parent() && (gurl.SchemeIs(content::kHttpScheme) || 97 gurl.SchemeIs(content::kHttpsScheme) || 98 gurl.SchemeIs(chrome::kAboutScheme))) 99 return false; 100 101 // use NavigationInterception throttle to handle the call as that can 102 // be deferred until after the java side has been constructed. 103 if (opener_id != MSG_ROUTING_NONE) { 104 return false; 105 } 106 107 bool ignore_navigation = false; 108 base::string16 url = request.url().string(); 109 110 int routing_id = view->GetRoutingID(); 111 RenderThread::Get()->Send(new AwViewHostMsg_ShouldOverrideUrlLoading( 112 routing_id, url, &ignore_navigation)); 113 return ignore_navigation; 114 } 115 116 void AwContentRendererClient::RenderViewCreated( 117 content::RenderView* render_view) { 118 AwRenderViewExt::RenderViewCreated(render_view); 119 120 new printing::PrintWebViewHelper(render_view); 121 // TODO(sgurun) do not create a password autofill agent (change 122 // autofill agent to store a weakptr). 123 autofill::PasswordAutofillAgent* password_autofill_agent = 124 new autofill::PasswordAutofillAgent(render_view); 125 new autofill::AutofillAgent(render_view, password_autofill_agent); 126 } 127 128 std::string AwContentRendererClient::GetDefaultEncoding() { 129 return AwResource::GetDefaultTextEncoding(); 130 } 131 132 bool AwContentRendererClient::HasErrorPage(int http_status_code, 133 std::string* error_domain) { 134 return http_status_code >= 400; 135 } 136 137 void AwContentRendererClient::GetNavigationErrorStrings( 138 blink::WebFrame* /* frame */, 139 const blink::WebURLRequest& failed_request, 140 const blink::WebURLError& error, 141 const std::string& accept_languages, 142 std::string* error_html, 143 string16* error_description) { 144 if (error_html) { 145 GURL error_url(failed_request.url()); 146 std::string err = UTF16ToUTF8(error.localizedDescription); 147 std::string contents; 148 if (err.empty()) { 149 contents = AwResource::GetNoDomainPageContent(); 150 } else { 151 contents = AwResource::GetLoadErrorPageContent(); 152 ReplaceSubstringsAfterOffset(&contents, 0, "%e", err); 153 } 154 155 ReplaceSubstringsAfterOffset(&contents, 0, "%s", 156 net::EscapeForHTML(error_url.possibly_invalid_spec())); 157 *error_html = contents; 158 } 159 if (error_description) { 160 if (error.localizedDescription.isEmpty()) 161 *error_description = ASCIIToUTF16(net::ErrorToString(error.reason)); 162 else 163 *error_description = error.localizedDescription; 164 } 165 } 166 167 unsigned long long AwContentRendererClient::VisitedLinkHash( 168 const char* canonical_url, 169 size_t length) { 170 return visited_link_slave_->ComputeURLFingerprint(canonical_url, length); 171 } 172 173 bool AwContentRendererClient::IsLinkVisited(unsigned long long link_hash) { 174 return visited_link_slave_->IsVisited(link_hash); 175 } 176 177 void AwContentRendererClient::AddKeySystems( 178 std::vector<content::KeySystemInfo>* key_systems) { 179 AwAddKeySystems(key_systems); 180 } 181 182 } // namespace android_webview 183