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