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 virtual void DidCommitProvisionalLoad(bool is_new_navigation) OVERRIDE {
78 blink::WebFrame* frame = render_frame()->GetWebFrame();
79 GURL url(frame->document().url());
80 if (url.SchemeIs(application::kApplicationScheme)) {
81 blink::WebSecurityOrigin origin = frame->document().securityOrigin();
82 origin.grantLoadLocalResources();
88 extensions::XWalkExtensionRendererController* extension_controller_;
90 DISALLOW_COPY_AND_ASSIGN(XWalkFrameHelper);
95 XWalkContentRendererClient* XWalkContentRendererClient::Get() {
96 return g_renderer_client;
99 XWalkContentRendererClient::XWalkContentRendererClient() {
100 DCHECK(!g_renderer_client);
101 g_renderer_client = this;
104 XWalkContentRendererClient::~XWalkContentRendererClient() {
105 g_renderer_client = NULL;
108 void XWalkContentRendererClient::RenderThreadStarted() {
109 CommandLine* cmd_line = CommandLine::ForCurrentProcess();
110 if (!cmd_line->HasSwitch(switches::kXWalkDisableExtensions))
111 extension_controller_.reset(
112 new extensions::XWalkExtensionRendererController(this));
114 blink::WebString application_scheme(
115 base::ASCIIToUTF16(application::kApplicationScheme));
116 blink::WebSecurityPolicy::registerURLSchemeAsSecure(application_scheme);
117 blink::WebSecurityPolicy::registerURLSchemeAsCORSEnabled(application_scheme);
119 content::RenderThread* thread = content::RenderThread::Get();
120 xwalk_render_process_observer_.reset(new XWalkRenderProcessObserver);
121 thread->AddObserver(xwalk_render_process_observer_.get());
122 #if defined(OS_ANDROID)
123 blink::WebString content_scheme(
124 base::ASCIIToUTF16(xwalk::kContentScheme));
125 blink::WebSecurityPolicy::registerURLSchemeAsLocal(content_scheme);
127 visited_link_slave_.reset(new visitedlink::VisitedLinkSlave);
128 thread->AddObserver(visited_link_slave_.get());
132 void XWalkContentRendererClient::RenderFrameCreated(
133 content::RenderFrame* render_frame) {
134 new XWalkFrameHelper(render_frame, extension_controller_.get());
135 #if defined(OS_ANDROID)
136 new XWalkPermissionClient(render_frame);
139 #if defined(ENABLE_PLUGINS)
140 new PepperHelper(render_frame);
144 void XWalkContentRendererClient::RenderViewCreated(
145 content::RenderView* render_view) {
146 #if defined(OS_ANDROID)
147 XWalkRenderViewExt::RenderViewCreated(render_view);
148 #elif defined(OS_TIZEN)
149 XWalkRenderViewExtTizen::RenderViewCreated(render_view);
153 void XWalkContentRendererClient::DidCreateScriptContext(
154 blink::WebFrame* frame, v8::Handle<v8::Context> context,
155 int extension_group, int world_id) {
156 if (extension_controller_)
157 extension_controller_->DidCreateScriptContext(frame, context);
158 #if !defined(OS_ANDROID)
159 xwalk_render_process_observer_->DidCreateScriptContext(
160 frame, context, extension_group, world_id);
164 void XWalkContentRendererClient::DidCreateModuleSystem(
165 extensions::XWalkModuleSystem* module_system) {
166 scoped_ptr<extensions::XWalkNativeModule> app_module(
167 new application::ApplicationNativeModule());
168 module_system->RegisterNativeModule("application", app_module.Pass());
169 scoped_ptr<extensions::XWalkNativeModule> isolated_file_system_module(
170 new extensions::IsolatedFileSystem());
171 module_system->RegisterNativeModule("isolated_file_system",
172 isolated_file_system_module.Pass());
173 module_system->RegisterNativeModule("sysapps_common",
174 extensions::CreateJSModuleFromResource(IDR_XWALK_SYSAPPS_COMMON_API));
175 module_system->RegisterNativeModule("sysapps_promise",
176 extensions::CreateJSModuleFromResource(
177 IDR_XWALK_SYSAPPS_COMMON_PROMISE_API));
178 module_system->RegisterNativeModule("widget_common",
179 extensions::CreateJSModuleFromResource(
180 IDR_XWALK_APPLICATION_WIDGET_COMMON_API));
183 const void* XWalkContentRendererClient::CreatePPAPIInterface(
184 const std::string& interface_name) {
185 #if defined(ENABLE_PLUGINS) && !defined(DISABLE_NACL)
186 if (interface_name == PPB_NACL_PRIVATE_INTERFACE)
187 return nacl::GetNaClPrivateInterface();
192 bool XWalkContentRendererClient::IsExternalPepperPlugin(
193 const std::string& module_name) {
194 // TODO(bbudge) remove this when the trusted NaCl plugin has been removed.
195 // We must defer certain plugin events for NaCl instances since we switch
196 // from the in-process to the out-of-process proxy after instantiating them.
197 return module_name == "Native Client";
200 #if defined(OS_ANDROID)
201 unsigned long long XWalkContentRendererClient::VisitedLinkHash( // NOLINT
202 const char* canonical_url, size_t length) {
203 return visited_link_slave_->ComputeURLFingerprint(canonical_url, length);
206 bool XWalkContentRendererClient::IsLinkVisited(unsigned long long link_hash) { // NOLINT
207 return visited_link_slave_->IsVisited(link_hash);
211 bool XWalkContentRendererClient::WillSendRequest(blink::WebFrame* frame,
212 content::PageTransition transition_type,
214 const GURL& first_party_for_cookies,
216 #if defined(OS_ANDROID)
219 if (!xwalk_render_process_observer_->IsWarpMode()
220 #if defined(OS_TIZEN)
221 && !xwalk_render_process_observer_->IsCSPMode()
226 GURL origin_url(frame->document().url());
227 GURL app_url(xwalk_render_process_observer_->app_url());
228 #if defined(OS_TIZEN)
229 // if under CSP mode.
230 if (xwalk_render_process_observer_->IsCSPMode()) {
231 if (url.GetOrigin() != app_url.GetOrigin() &&
232 origin_url != first_party_for_cookies &&
233 !first_party_for_cookies.is_empty() &&
234 first_party_for_cookies.GetOrigin() != app_url.GetOrigin() &&
235 !blink::WebSecurityOrigin::create(app_url).canRequest(url)) {
236 LOG(INFO) << "[BLOCK] allow-navigation: " << url.spec();
237 content::RenderThread::Get()->Send(new ViewMsg_OpenLinkExternal(url));
244 // if under WARP mode.
245 if (url.GetOrigin() == app_url.GetOrigin() ||
246 frame->document().securityOrigin().canRequest(url)) {
247 LOG(INFO) << "[PASS] " << origin_url.spec() << " request " << url.spec();
251 LOG(INFO) << "[BLOCK] " << origin_url.spec() << " request " << url.spec();
252 #if defined(OS_TIZEN)
253 if (url.GetOrigin() != app_url.GetOrigin() &&
254 origin_url != first_party_for_cookies &&
255 first_party_for_cookies.GetOrigin() != app_url.GetOrigin())
256 content::RenderThread::Get()->Send(new ViewMsg_OpenLinkExternal(url));
264 void XWalkContentRendererClient::GetNavigationErrorStrings(
265 content::RenderView* render_view,
266 blink::WebFrame* frame,
267 const blink::WebURLRequest& failed_request,
268 const blink::WebURLError& error,
269 std::string* error_html,
270 base::string16* error_description) {
271 bool is_post = EqualsASCII(failed_request.httpMethod(), "POST");
273 // TODO(guangzhen): Check whether error_html is needed in xwalk runtime.
275 if (error_description) {
276 *error_description = LocalizedError::GetErrorDetails(error, is_post);