Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / xwalk / extensions / renderer / xwalk_extension_renderer_controller.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/extensions/renderer/xwalk_extension_renderer_controller.h"
6
7 #include "base/command_line.h"
8 #include "base/values.h"
9 #include "content/public/renderer/render_thread.h"
10 #include "content/public/renderer/v8_value_converter.h"
11 #include "grit/xwalk_extensions_resources.h"
12 #include "ipc/ipc_channel_handle.h"
13 #include "ipc/ipc_listener.h"
14 #include "ipc/ipc_sync_channel.h"
15 #include "third_party/WebKit/public/web/WebDocument.h"
16 #include "third_party/WebKit/public/web/WebFrame.h"
17 #include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h"
18 #include "v8/include/v8.h"
19 #include "xwalk/extensions/common/xwalk_extension_messages.h"
20 #include "xwalk/extensions/common/xwalk_extension_switches.h"
21 #include "xwalk/extensions/renderer/xwalk_extension_client.h"
22 #include "xwalk/extensions/renderer/xwalk_extension_module.h"
23 #include "xwalk/extensions/renderer/xwalk_js_module.h"
24 #include "xwalk/extensions/renderer/xwalk_module_system.h"
25 #include "xwalk/extensions/renderer/xwalk_v8tools_module.h"
26
27 #if defined(OS_TIZEN)
28 #include "xwalk/application/common/constants.h"
29 #endif
30
31 namespace xwalk {
32 namespace extensions {
33
34 const GURL kAboutBlankURL = GURL("about:blank");
35
36 XWalkExtensionRendererController::XWalkExtensionRendererController(
37     Delegate* delegate)
38     : shutdown_event_(false, false),
39       delegate_(delegate) {
40   content::RenderThread* thread = content::RenderThread::Get();
41   thread->AddObserver(this);
42   IPC::SyncChannel* browser_channel = thread->GetChannel();
43   SetupBrowserProcessClient(browser_channel);
44
45   CommandLine* cmd_line = CommandLine::ForCurrentProcess();
46   if (cmd_line->HasSwitch(switches::kXWalkDisableExtensionProcess))
47     LOG(INFO) << "EXTENSION PROCESS DISABLED.";
48   else
49     SetupExtensionProcessClient(browser_channel);
50 }
51
52 XWalkExtensionRendererController::~XWalkExtensionRendererController() {
53   // FIXME(cmarcelo): These call is causing crashes on shutdown with Chromium
54   //                  29.0.1547.57 and had to be commented out.
55   // content::RenderThread::Get()->RemoveObserver(this);
56 }
57
58 namespace {
59
60 void CreateExtensionModules(XWalkExtensionClient* client,
61                             XWalkModuleSystem* module_system) {
62   const XWalkExtensionClient::ExtensionAPIMap& extensions =
63       client->extension_apis();
64   XWalkExtensionClient::ExtensionAPIMap::const_iterator it = extensions.begin();
65   for (; it != extensions.end(); ++it) {
66     XWalkExtensionClient::ExtensionCodePoints* codepoint = it->second;
67     if (codepoint->api.empty())
68       continue;
69     scoped_ptr<XWalkExtensionModule> module(
70         new XWalkExtensionModule(client, module_system,
71                                  it->first, codepoint->api));
72     module_system->RegisterExtensionModule(module.Pass(),
73                                            codepoint->entry_points);
74   }
75 }
76
77 #if defined(OS_TIZEN)
78 void CreateExtensionModulesWithoutDeviceAPI(XWalkExtensionClient* client,
79                                             XWalkModuleSystem* module_system) {
80   const XWalkExtensionClient::ExtensionAPIMap& extensions =
81       client->extension_apis();
82   XWalkExtensionClient::ExtensionAPIMap::const_iterator it = extensions.begin();
83   for (; it != extensions.end(); ++it) {
84     XWalkExtensionClient::ExtensionCodePoints* codepoint = it->second;
85     if (codepoint->api.empty() || it->first.find("tizen") == 0)
86       continue;
87     scoped_ptr<XWalkExtensionModule> module(
88         new XWalkExtensionModule(client, module_system,
89                                  it->first, codepoint->api));
90     module_system->RegisterExtensionModule(module.Pass(),
91                                            codepoint->entry_points);
92   }
93 }
94 #endif
95 }  // namespace
96
97 void XWalkExtensionRendererController::DidCreateScriptContext(
98     blink::WebFrame* frame, v8::Handle<v8::Context> context) {
99   XWalkModuleSystem* module_system = new XWalkModuleSystem(context);
100   XWalkModuleSystem::SetModuleSystemInContext(
101       scoped_ptr<XWalkModuleSystem>(module_system), context);
102
103   module_system->RegisterNativeModule(
104       "v8tools", scoped_ptr<XWalkNativeModule>(new XWalkV8ToolsModule));
105   module_system->RegisterNativeModule(
106       "internal", CreateJSModuleFromResource(
107           IDR_XWALK_EXTENSIONS_INTERNAL_API));
108
109   delegate_->DidCreateModuleSystem(module_system);
110
111   CreateExtensionModules(in_browser_process_extensions_client_.get(),
112                          module_system);
113
114   if (external_extensions_client_) {
115 #if defined(OS_TIZEN)
116     // On Tizen platform, only local pages can access to device APIs.
117     GURL url = static_cast<GURL>(frame->document().url());
118     if (!url.SchemeIs(xwalk::application::kApplicationScheme) &&
119         !url.SchemeIsFile())
120       CreateExtensionModulesWithoutDeviceAPI(external_extensions_client_.get(),
121                                              module_system);
122     else
123       CreateExtensionModules(external_extensions_client_.get(), module_system);
124 #else
125     CreateExtensionModules(external_extensions_client_.get(),
126                            module_system);
127 #endif
128   }
129
130   module_system->Initialize();
131 }
132
133 void XWalkExtensionRendererController::WillReleaseScriptContext(
134     blink::WebLocalFrame* frame, v8::Handle<v8::Context> context) {
135   v8::Context::Scope contextScope(context);
136   XWalkModuleSystem::ResetModuleSystemFromContext(context);
137 }
138
139 bool XWalkExtensionRendererController::OnControlMessageReceived(
140     const IPC::Message& message) {
141   return in_browser_process_extensions_client_->OnMessageReceived(message);
142 }
143
144 void XWalkExtensionRendererController::OnRenderProcessShutdown() {
145   shutdown_event_.Signal();
146 }
147
148 void XWalkExtensionRendererController::SetupBrowserProcessClient(
149     IPC::SyncChannel* browser_channel) {
150   in_browser_process_extensions_client_.reset(new XWalkExtensionClient);
151   in_browser_process_extensions_client_->Initialize(browser_channel);
152 }
153
154 void XWalkExtensionRendererController::SetupExtensionProcessClient(
155     IPC::SyncChannel* browser_channel) {
156   IPC::ChannelHandle handle;
157   browser_channel->Send(
158       new XWalkExtensionProcessHostMsg_GetExtensionProcessChannel(&handle));
159   // FIXME(cmarcelo): Need to account for failure in creating the channel.
160
161   external_extensions_client_.reset(new XWalkExtensionClient);
162   extension_process_channel_ = IPC::SyncChannel::Create(handle,
163       IPC::Channel::MODE_CLIENT, external_extensions_client_.get(),
164       content::RenderThread::Get()->GetIOMessageLoopProxy(), true,
165       &shutdown_event_);
166
167   external_extensions_client_->Initialize(extension_process_channel_.get());
168 }
169
170
171 }  // namespace extensions
172 }  // namespace xwalk