1 // Copyright (c) 2013 Intel Corporation. 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.
5 #include "xwalk/runtime/renderer/xwalk_content_renderer_client.h"
7 #include "base/command_line.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "components/nacl/renderer/ppb_nacl_private_impl.h"
10 #include "components/visitedlink/renderer/visitedlink_slave.h"
11 #include "content/public/renderer/render_frame.h"
12 #include "content/public/renderer/render_frame_observer.h"
13 #include "content/public/renderer/render_frame_observer_tracker.h"
14 #include "content/public/renderer/render_thread.h"
15 #include "grit/xwalk_application_resources.h"
16 #include "grit/xwalk_sysapps_resources.h"
17 #include "third_party/WebKit/public/platform/WebString.h"
18 #include "third_party/WebKit/public/platform/WebURLRequest.h"
19 #include "third_party/WebKit/public/web/WebDocument.h"
20 #include "third_party/WebKit/public/web/WebSecurityPolicy.h"
21 #include "xwalk/application/common/constants.h"
22 #include "xwalk/application/renderer/application_native_module.h"
23 #include "xwalk/extensions/common/xwalk_extension_switches.h"
24 #include "xwalk/extensions/renderer/xwalk_js_module.h"
25 #include "xwalk/runtime/common/xwalk_localized_error.h"
26 #include "xwalk/runtime/renderer/isolated_file_system.h"
27 #include "xwalk/runtime/renderer/pepper/pepper_helper.h"
29 #if defined(OS_ANDROID)
30 #include "xwalk/runtime/browser/android/net/url_constants.h"
31 #include "xwalk/runtime/renderer/android/xwalk_permission_client.h"
32 #include "xwalk/runtime/renderer/android/xwalk_render_process_observer.h"
33 #include "xwalk/runtime/renderer/android/xwalk_render_view_ext.h"
35 #include "third_party/WebKit/public/web/WebFrame.h"
39 #include "xwalk/runtime/common/xwalk_common_messages.h"
42 #if defined(OS_TIZEN_MOBILE)
43 #include "xwalk/runtime/renderer/tizen/xwalk_content_renderer_client_tizen.h"
47 #include "xwalk/runtime/renderer/tizen/xwalk_render_view_ext_tizen.h"
54 xwalk::XWalkContentRendererClient* g_renderer_client;
56 class XWalkFrameHelper
57 : public content::RenderFrameObserver,
58 public content::RenderFrameObserverTracker<XWalkFrameHelper> {
61 content::RenderFrame* render_frame,
62 extensions::XWalkExtensionRendererController* extension_controller)
63 : content::RenderFrameObserver(render_frame),
64 content::RenderFrameObserverTracker<XWalkFrameHelper>(render_frame),
65 extension_controller_(extension_controller) {}
66 virtual ~XWalkFrameHelper() {}
68 // RenderFrameObserver implementation.
69 virtual void WillReleaseScriptContext(v8::Handle<v8::Context> context,
70 int world_id) OVERRIDE {
71 if (extension_controller_)
72 extension_controller_->WillReleaseScriptContext(
73 render_frame()->GetWebFrame(), context);
77 extensions::XWalkExtensionRendererController* extension_controller_;
79 DISALLOW_COPY_AND_ASSIGN(XWalkFrameHelper);
84 XWalkContentRendererClient* XWalkContentRendererClient::Get() {
85 return g_renderer_client;
88 XWalkContentRendererClient::XWalkContentRendererClient() {
89 DCHECK(!g_renderer_client);
90 g_renderer_client = this;
93 XWalkContentRendererClient::~XWalkContentRendererClient() {
94 g_renderer_client = NULL;
97 void XWalkContentRendererClient::RenderThreadStarted() {
98 #if defined(OS_ANDROID)
99 CommandLine* cmd_line = CommandLine::ForCurrentProcess();
100 if (!cmd_line->HasSwitch(switches::kXWalkDisableExtensions))
103 extension_controller_.reset(
104 new extensions::XWalkExtensionRendererController(this));
107 blink::WebString application_scheme(
108 base::ASCIIToUTF16(application::kApplicationScheme));
109 blink::WebSecurityPolicy::registerURLSchemeAsSecure(application_scheme);
110 blink::WebSecurityPolicy::registerURLSchemeAsCORSEnabled(application_scheme);
112 content::RenderThread* thread = content::RenderThread::Get();
113 xwalk_render_process_observer_.reset(new XWalkRenderProcessObserver);
114 thread->AddObserver(xwalk_render_process_observer_.get());
115 #if defined(OS_ANDROID)
116 blink::WebString content_scheme(
117 base::ASCIIToUTF16(xwalk::kContentScheme));
118 blink::WebSecurityPolicy::registerURLSchemeAsLocal(content_scheme);
120 visited_link_slave_.reset(new visitedlink::VisitedLinkSlave);
121 thread->AddObserver(visited_link_slave_.get());
125 void XWalkContentRendererClient::RenderFrameCreated(
126 content::RenderFrame* render_frame) {
127 new XWalkFrameHelper(render_frame, extension_controller_.get());
128 #if defined(OS_ANDROID)
129 new XWalkPermissionClient(render_frame);
132 #if defined(ENABLE_PLUGINS)
133 new PepperHelper(render_frame);
137 void XWalkContentRendererClient::RenderViewCreated(
138 content::RenderView* render_view) {
139 #if defined(OS_ANDROID)
140 XWalkRenderViewExt::RenderViewCreated(render_view);
141 #elif defined(OS_TIZEN)
142 XWalkRenderViewExtTizen::RenderViewCreated(render_view);
146 void XWalkContentRendererClient::DidCreateScriptContext(
147 blink::WebFrame* frame, v8::Handle<v8::Context> context,
148 int extension_group, int world_id) {
149 if (extension_controller_)
150 extension_controller_->DidCreateScriptContext(frame, context);
151 #if !defined(OS_ANDROID)
152 xwalk_render_process_observer_->DidCreateScriptContext(
153 frame, context, extension_group, world_id);
157 void XWalkContentRendererClient::DidCreateModuleSystem(
158 extensions::XWalkModuleSystem* module_system) {
159 scoped_ptr<extensions::XWalkNativeModule> app_module(
160 new application::ApplicationNativeModule());
161 module_system->RegisterNativeModule("application", app_module.Pass());
162 scoped_ptr<extensions::XWalkNativeModule> isolated_file_system_module(
163 new extensions::IsolatedFileSystem());
164 module_system->RegisterNativeModule("isolated_file_system",
165 isolated_file_system_module.Pass());
166 module_system->RegisterNativeModule("sysapps_common",
167 extensions::CreateJSModuleFromResource(IDR_XWALK_SYSAPPS_COMMON_API));
168 module_system->RegisterNativeModule("sysapps_promise",
169 extensions::CreateJSModuleFromResource(
170 IDR_XWALK_SYSAPPS_COMMON_PROMISE_API));
171 module_system->RegisterNativeModule("widget_common",
172 extensions::CreateJSModuleFromResource(
173 IDR_XWALK_APPLICATION_WIDGET_COMMON_API));
176 const void* XWalkContentRendererClient::CreatePPAPIInterface(
177 const std::string& interface_name) {
178 #if defined(ENABLE_PLUGINS) && !defined(DISABLE_NACL)
179 if (interface_name == PPB_NACL_PRIVATE_INTERFACE)
180 return nacl::GetNaClPrivateInterface();
185 bool XWalkContentRendererClient::IsExternalPepperPlugin(
186 const std::string& module_name) {
187 // TODO(bbudge) remove this when the trusted NaCl plugin has been removed.
188 // We must defer certain plugin events for NaCl instances since we switch
189 // from the in-process to the out-of-process proxy after instantiating them.
190 return module_name == "Native Client";
193 #if defined(OS_ANDROID)
194 unsigned long long XWalkContentRendererClient::VisitedLinkHash( // NOLINT
195 const char* canonical_url, size_t length) {
196 return visited_link_slave_->ComputeURLFingerprint(canonical_url, length);
199 bool XWalkContentRendererClient::IsLinkVisited(unsigned long long link_hash) { // NOLINT
200 return visited_link_slave_->IsVisited(link_hash);
204 bool XWalkContentRendererClient::WillSendRequest(blink::WebFrame* frame,
205 content::PageTransition transition_type,
207 const GURL& first_party_for_cookies,
209 #if defined(OS_ANDROID)
212 if (!xwalk_render_process_observer_->IsWarpMode()
213 #if defined(OS_TIZEN)
214 && !xwalk_render_process_observer_->IsCSPMode()
219 GURL origin_url(frame->document().url());
220 GURL app_url(xwalk_render_process_observer_->app_url());
221 #if defined(OS_TIZEN)
222 // if under CSP mode.
223 if (xwalk_render_process_observer_->IsCSPMode()) {
224 if (url.GetOrigin() != app_url.GetOrigin() &&
225 origin_url != first_party_for_cookies &&
226 !first_party_for_cookies.is_empty() &&
227 first_party_for_cookies.GetOrigin() != app_url.GetOrigin() &&
228 !blink::WebSecurityOrigin::create(app_url).canRequest(url)) {
229 LOG(INFO) << "[BLOCK] allow-navigation: " << url.spec();
230 content::RenderThread::Get()->Send(new ViewMsg_OpenLinkExternal(url));
237 // if under WARP mode.
238 if (url.GetOrigin() == app_url.GetOrigin() ||
239 frame->document().securityOrigin().canRequest(url)) {
240 LOG(INFO) << "[PASS] " << origin_url.spec() << " request " << url.spec();
244 LOG(INFO) << "[BLOCK] " << origin_url.spec() << " request " << url.spec();
245 #if defined(OS_TIZEN)
246 if (url.GetOrigin() != app_url.GetOrigin() &&
247 origin_url != first_party_for_cookies &&
248 first_party_for_cookies.GetOrigin() != app_url.GetOrigin())
249 content::RenderThread::Get()->Send(new ViewMsg_OpenLinkExternal(url));
257 void XWalkContentRendererClient::GetNavigationErrorStrings(
258 content::RenderView* render_view,
259 blink::WebFrame* frame,
260 const blink::WebURLRequest& failed_request,
261 const blink::WebURLError& error,
262 std::string* error_html,
263 base::string16* error_description) {
264 bool is_post = EqualsASCII(failed_request.httpMethod(), "POST");
266 // TODO(guangzhen): Check whether error_html is needed in xwalk runtime.
268 if (error_description) {
269 *error_description = LocalizedError::GetErrorDetails(error, is_post);