Upstream version 8.36.161.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/strings/utf_string_conversions.h"
8 #include "components/nacl/renderer/ppb_nacl_private_impl.h"
9 #include "components/visitedlink/renderer/visitedlink_slave.h"
10 #include "content/public/renderer/render_frame.h"
11 #include "content/public/renderer/render_frame_observer.h"
12 #include "content/public/renderer/render_frame_observer_tracker.h"
13 #include "content/public/renderer/render_thread.h"
14 #include "grit/xwalk_application_resources.h"
15 #include "grit/xwalk_sysapps_resources.h"
16 #include "third_party/WebKit/public/platform/WebString.h"
17 #include "third_party/WebKit/public/platform/WebURLRequest.h"
18 #include "third_party/WebKit/public/web/WebDocument.h"
19 #include "third_party/WebKit/public/web/WebSecurityPolicy.h"
20 #include "xwalk/application/common/constants.h"
21 #include "xwalk/application/renderer/application_native_module.h"
22 #include "xwalk/extensions/renderer/xwalk_js_module.h"
23 #include "xwalk/runtime/common/xwalk_localized_error.h"
24 #include "xwalk/runtime/renderer/isolated_file_system.h"
25 #include "xwalk/runtime/renderer/pepper/pepper_helper.h"
26
27 #if defined(OS_ANDROID)
28 #include "xwalk/runtime/browser/android/net/url_constants.h"
29 #include "xwalk/runtime/renderer/android/xwalk_permission_client.h"
30 #include "xwalk/runtime/renderer/android/xwalk_render_process_observer.h"
31 #include "xwalk/runtime/renderer/android/xwalk_render_view_ext.h"
32 #else
33 #include "third_party/WebKit/public/web/WebFrame.h"
34 #endif
35
36 #if defined(OS_TIZEN)
37 #include "xwalk/runtime/common/xwalk_common_messages.h"
38 #endif
39
40 #if defined(OS_TIZEN_MOBILE)
41 #include "xwalk/runtime/renderer/tizen/xwalk_content_renderer_client_tizen.h"
42 #endif
43
44 #if defined(OS_TIZEN)
45 #include "xwalk/runtime/renderer/tizen/xwalk_render_view_ext_tizen.h"
46 #endif
47
48 namespace xwalk {
49
50 namespace {
51
52 xwalk::XWalkContentRendererClient* g_renderer_client;
53
54 class XWalkFrameHelper
55     : public content::RenderFrameObserver,
56       public content::RenderFrameObserverTracker<XWalkFrameHelper> {
57  public:
58   XWalkFrameHelper(
59       content::RenderFrame* render_frame,
60       extensions::XWalkExtensionRendererController* extension_controller)
61       : content::RenderFrameObserver(render_frame),
62         content::RenderFrameObserverTracker<XWalkFrameHelper>(render_frame),
63         extension_controller_(extension_controller) {}
64   virtual ~XWalkFrameHelper() {}
65
66   // RenderFrameObserver implementation.
67   virtual void WillReleaseScriptContext(v8::Handle<v8::Context> context,
68                                         int world_id) OVERRIDE {
69     extension_controller_->WillReleaseScriptContext(
70         render_frame()->GetWebFrame(), context);
71   }
72
73  private:
74   extensions::XWalkExtensionRendererController* extension_controller_;
75
76   DISALLOW_COPY_AND_ASSIGN(XWalkFrameHelper);
77 };
78
79 }  // namespace
80
81 XWalkContentRendererClient* XWalkContentRendererClient::Get() {
82   return g_renderer_client;
83 }
84
85 XWalkContentRendererClient::XWalkContentRendererClient() {
86   DCHECK(!g_renderer_client);
87   g_renderer_client = this;
88 }
89
90 XWalkContentRendererClient::~XWalkContentRendererClient() {
91   g_renderer_client = NULL;
92 }
93
94 void XWalkContentRendererClient::RenderThreadStarted() {
95   extension_controller_.reset(
96       new extensions::XWalkExtensionRendererController(this));
97
98   blink::WebString application_scheme(
99       base::ASCIIToUTF16(application::kApplicationScheme));
100   blink::WebSecurityPolicy::registerURLSchemeAsSecure(application_scheme);
101   blink::WebSecurityPolicy::registerURLSchemeAsCORSEnabled(application_scheme);
102
103   content::RenderThread* thread = content::RenderThread::Get();
104   xwalk_render_process_observer_.reset(new XWalkRenderProcessObserver);
105   thread->AddObserver(xwalk_render_process_observer_.get());
106 #if defined(OS_ANDROID)
107   blink::WebString content_scheme(
108       base::ASCIIToUTF16(xwalk::kContentScheme));
109   blink::WebSecurityPolicy::registerURLSchemeAsLocal(content_scheme);
110
111   visited_link_slave_.reset(new visitedlink::VisitedLinkSlave);
112   thread->AddObserver(visited_link_slave_.get());
113 #endif
114 }
115
116 void XWalkContentRendererClient::RenderFrameCreated(
117     content::RenderFrame* render_frame) {
118   new XWalkFrameHelper(render_frame, extension_controller_.get());
119 #if defined(OS_ANDROID)
120   new XWalkPermissionClient(render_frame);
121 #endif
122
123 #if defined(ENABLE_PLUGINS)
124   new PepperHelper(render_frame);
125 #endif
126 }
127
128 void XWalkContentRendererClient::RenderViewCreated(
129     content::RenderView* render_view) {
130 #if defined(OS_ANDROID)
131   XWalkRenderViewExt::RenderViewCreated(render_view);
132 #elif defined(OS_TIZEN)
133   XWalkRenderViewExtTizen::RenderViewCreated(render_view);
134 #endif
135 }
136
137 void XWalkContentRendererClient::DidCreateScriptContext(
138     blink::WebFrame* frame, v8::Handle<v8::Context> context,
139     int extension_group, int world_id) {
140   extension_controller_->DidCreateScriptContext(frame, context);
141 #if !defined(OS_ANDROID)
142   xwalk_render_process_observer_->DidCreateScriptContext(
143       frame, context, extension_group, world_id);
144 #endif
145 }
146
147 void XWalkContentRendererClient::DidCreateModuleSystem(
148     extensions::XWalkModuleSystem* module_system) {
149   scoped_ptr<extensions::XWalkNativeModule> app_module(
150       new application::ApplicationNativeModule());
151   module_system->RegisterNativeModule("application", app_module.Pass());
152   scoped_ptr<extensions::XWalkNativeModule> isolated_file_system_module(
153       new extensions::IsolatedFileSystem());
154   module_system->RegisterNativeModule("isolated_file_system",
155       isolated_file_system_module.Pass());
156   module_system->RegisterNativeModule("sysapps_common",
157       extensions::CreateJSModuleFromResource(IDR_XWALK_SYSAPPS_COMMON_API));
158   module_system->RegisterNativeModule("sysapps_promise",
159       extensions::CreateJSModuleFromResource(
160           IDR_XWALK_SYSAPPS_COMMON_PROMISE_API));
161   module_system->RegisterNativeModule("widget_common",
162       extensions::CreateJSModuleFromResource(
163           IDR_XWALK_APPLICATION_WIDGET_COMMON_API));
164 }
165
166 const void* XWalkContentRendererClient::CreatePPAPIInterface(
167     const std::string& interface_name) {
168 #if defined(ENABLE_PLUGINS) && !defined(DISABLE_NACL)
169   if (interface_name == PPB_NACL_PRIVATE_INTERFACE)
170     return nacl::GetNaClPrivateInterface();
171 #endif
172   return NULL;
173 }
174
175 bool XWalkContentRendererClient::IsExternalPepperPlugin(
176     const std::string& module_name) {
177   // TODO(bbudge) remove this when the trusted NaCl plugin has been removed.
178   // We must defer certain plugin events for NaCl instances since we switch
179   // from the in-process to the out-of-process proxy after instantiating them.
180   return module_name == "Native Client";
181 }
182
183 #if defined(OS_ANDROID)
184 unsigned long long XWalkContentRendererClient::VisitedLinkHash( // NOLINT
185     const char* canonical_url, size_t length) {
186   return visited_link_slave_->ComputeURLFingerprint(canonical_url, length);
187 }
188
189 bool XWalkContentRendererClient::IsLinkVisited(unsigned long long link_hash) { // NOLINT
190   return visited_link_slave_->IsVisited(link_hash);
191 }
192 #endif
193
194 bool XWalkContentRendererClient::WillSendRequest(blink::WebFrame* frame,
195                      content::PageTransition transition_type,
196                      const GURL& url,
197                      const GURL& first_party_for_cookies,
198                      GURL* new_url) {
199 #if defined(OS_ANDROID)
200   return false;
201 #else
202   if (!xwalk_render_process_observer_->IsWarpMode()
203 #if defined(OS_TIZEN)
204       && !xwalk_render_process_observer_->IsCSPMode()
205 #endif
206       )
207     return false;
208
209   GURL origin_url(frame->document().url());
210   GURL app_url(xwalk_render_process_observer_->app_url());
211 #if defined(OS_TIZEN)
212   // if under CSP mode.
213   if (xwalk_render_process_observer_->IsCSPMode()) {
214     if (url.GetOrigin() != app_url.GetOrigin() &&
215         origin_url != first_party_for_cookies &&
216         !first_party_for_cookies.is_empty() &&
217         first_party_for_cookies.GetOrigin() != app_url.GetOrigin() &&
218         !blink::WebSecurityOrigin::create(app_url).canRequest(url)) {
219       LOG(INFO) << "[BLOCK] allow-navigation: " << url.spec();
220       content::RenderThread::Get()->Send(new ViewMsg_OpenLinkExternal(url));
221       *new_url = GURL();
222       return true;
223     }
224     return false;
225   }
226 #endif
227   // if under WARP mode.
228   if (url.GetOrigin() == app_url.GetOrigin() ||
229       frame->document().securityOrigin().canRequest(url)) {
230     LOG(INFO) << "[PASS] " << origin_url.spec() << " request " << url.spec();
231     return false;
232   }
233
234   LOG(INFO) << "[BLOCK] " << origin_url.spec() << " request " << url.spec();
235 #if defined(OS_TIZEN)
236   if (url.GetOrigin() != app_url.GetOrigin() &&
237       origin_url != first_party_for_cookies &&
238       first_party_for_cookies.GetOrigin() != app_url.GetOrigin())
239     content::RenderThread::Get()->Send(new ViewMsg_OpenLinkExternal(url));
240 #endif
241
242   *new_url = GURL();
243   return true;
244 #endif
245 }
246
247 void XWalkContentRendererClient::GetNavigationErrorStrings(
248     content::RenderView* render_view,
249     blink::WebFrame* frame,
250     const blink::WebURLRequest& failed_request,
251     const blink::WebURLError& error,
252     std::string* error_html,
253     base::string16* error_description) {
254   bool is_post = EqualsASCII(failed_request.httpMethod(), "POST");
255
256   // TODO(guangzhen): Check whether error_html is needed in xwalk runtime.
257
258   if (error_description) {
259     *error_description = LocalizedError::GetErrorDetails(error, is_post);
260   }
261 }
262
263 }  // namespace xwalk