Upstream version 8.37.183.0
[platform/framework/web/crosswalk.git] / src / xwalk / runtime / renderer / xwalk_content_renderer_client.cc
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.
4
5 #include "xwalk/runtime/renderer/xwalk_content_renderer_client.h"
6
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"
28
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"
34 #else
35 #include "third_party/WebKit/public/web/WebFrame.h"
36 #endif
37
38 #if defined(OS_TIZEN)
39 #include "xwalk/runtime/common/xwalk_common_messages.h"
40 #endif
41
42 #if defined(OS_TIZEN_MOBILE)
43 #include "xwalk/runtime/renderer/tizen/xwalk_content_renderer_client_tizen.h"
44 #endif
45
46 #if defined(OS_TIZEN)
47 #include "xwalk/runtime/renderer/tizen/xwalk_render_view_ext_tizen.h"
48 #endif
49
50 namespace xwalk {
51
52 namespace {
53
54 xwalk::XWalkContentRendererClient* g_renderer_client;
55
56 class XWalkFrameHelper
57     : public content::RenderFrameObserver,
58       public content::RenderFrameObserverTracker<XWalkFrameHelper> {
59  public:
60   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() {}
67
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);
74   }
75
76  private:
77   extensions::XWalkExtensionRendererController* extension_controller_;
78
79   DISALLOW_COPY_AND_ASSIGN(XWalkFrameHelper);
80 };
81
82 }  // namespace
83
84 XWalkContentRendererClient* XWalkContentRendererClient::Get() {
85   return g_renderer_client;
86 }
87
88 XWalkContentRendererClient::XWalkContentRendererClient() {
89   DCHECK(!g_renderer_client);
90   g_renderer_client = this;
91 }
92
93 XWalkContentRendererClient::~XWalkContentRendererClient() {
94   g_renderer_client = NULL;
95 }
96
97 void XWalkContentRendererClient::RenderThreadStarted() {
98 #if defined(OS_ANDROID)
99   CommandLine* cmd_line = CommandLine::ForCurrentProcess();
100   if (!cmd_line->HasSwitch(switches::kXWalkDisableExtensions))
101 #endif
102   {
103     extension_controller_.reset(
104         new extensions::XWalkExtensionRendererController(this));
105   }
106
107   blink::WebString application_scheme(
108       base::ASCIIToUTF16(application::kApplicationScheme));
109   blink::WebSecurityPolicy::registerURLSchemeAsSecure(application_scheme);
110   blink::WebSecurityPolicy::registerURLSchemeAsCORSEnabled(application_scheme);
111
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);
119
120   visited_link_slave_.reset(new visitedlink::VisitedLinkSlave);
121   thread->AddObserver(visited_link_slave_.get());
122 #endif
123 }
124
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);
130 #endif
131
132 #if defined(ENABLE_PLUGINS)
133   new PepperHelper(render_frame);
134 #endif
135 }
136
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);
143 #endif
144 }
145
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);
154 #endif
155 }
156
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));
174 }
175
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();
181 #endif
182   return NULL;
183 }
184
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";
191 }
192
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);
197 }
198
199 bool XWalkContentRendererClient::IsLinkVisited(unsigned long long link_hash) { // NOLINT
200   return visited_link_slave_->IsVisited(link_hash);
201 }
202 #endif
203
204 bool XWalkContentRendererClient::WillSendRequest(blink::WebFrame* frame,
205                      content::PageTransition transition_type,
206                      const GURL& url,
207                      const GURL& first_party_for_cookies,
208                      GURL* new_url) {
209 #if defined(OS_ANDROID)
210   return false;
211 #else
212   if (!xwalk_render_process_observer_->IsWarpMode()
213 #if defined(OS_TIZEN)
214       && !xwalk_render_process_observer_->IsCSPMode()
215 #endif
216       )
217     return false;
218
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));
231       *new_url = GURL();
232       return true;
233     }
234     return false;
235   }
236 #endif
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();
241     return false;
242   }
243
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));
250 #endif
251
252   *new_url = GURL();
253   return true;
254 #endif
255 }
256
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");
265
266   // TODO(guangzhen): Check whether error_html is needed in xwalk runtime.
267
268   if (error_description) {
269     *error_description = LocalizedError::GetErrorDetails(error, is_post);
270   }
271 }
272
273 }  // namespace xwalk