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