d3cc06292c528668f404277262f0427f091b146e
[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 namespace xwalk {
28 namespace extensions {
29
30 const GURL kAboutBlankURL = GURL("about:blank");
31
32 XWalkExtensionRendererController::XWalkExtensionRendererController(
33     Delegate* delegate)
34     : shutdown_event_(false, false),
35       delegate_(delegate) {
36   content::RenderThread* thread = content::RenderThread::Get();
37   thread->AddObserver(this);
38   IPC::SyncChannel* browser_channel = thread->GetChannel();
39   SetupBrowserProcessClient(browser_channel);
40
41   CommandLine* cmd_line = CommandLine::ForCurrentProcess();
42   if (cmd_line->HasSwitch(switches::kXWalkDisableExtensionProcess))
43     LOG(INFO) << "EXTENSION PROCESS DISABLED.";
44   else
45     SetupExtensionProcessClient(browser_channel);
46 }
47
48 XWalkExtensionRendererController::~XWalkExtensionRendererController() {
49   // FIXME(cmarcelo): These call is causing crashes on shutdown with Chromium
50   //                  29.0.1547.57 and had to be commented out.
51   // content::RenderThread::Get()->RemoveObserver(this);
52 }
53
54 namespace {
55
56 void CreateExtensionModules(XWalkExtensionClient* client,
57                             XWalkModuleSystem* module_system) {
58   const XWalkExtensionClient::ExtensionAPIMap& extensions =
59       client->extension_apis();
60   XWalkExtensionClient::ExtensionAPIMap::const_iterator it = extensions.begin();
61   for (; it != extensions.end(); ++it) {
62     XWalkExtensionClient::ExtensionCodePoints* codepoint = it->second;
63     if (codepoint->api.empty())
64       continue;
65     scoped_ptr<XWalkExtensionModule> module(
66         new XWalkExtensionModule(client, module_system,
67                                  it->first, codepoint->api));
68     module_system->RegisterExtensionModule(module.Pass(),
69                                            codepoint->entry_points);
70   }
71 }
72
73 }  // namespace
74
75 void XWalkExtensionRendererController::DidCreateScriptContext(
76     blink::WebFrame* frame, v8::Handle<v8::Context> context) {
77   XWalkModuleSystem* module_system = new XWalkModuleSystem(context);
78   XWalkModuleSystem::SetModuleSystemInContext(
79       scoped_ptr<XWalkModuleSystem>(module_system), context);
80
81   module_system->RegisterNativeModule(
82       "v8tools", scoped_ptr<XWalkNativeModule>(new XWalkV8ToolsModule));
83   module_system->RegisterNativeModule(
84       "internal", CreateJSModuleFromResource(
85           IDR_XWALK_EXTENSIONS_INTERNAL_API));
86
87   delegate_->DidCreateModuleSystem(module_system);
88
89   CreateExtensionModules(in_browser_process_extensions_client_.get(),
90                          module_system);
91
92   if (external_extensions_client_) {
93     CreateExtensionModules(external_extensions_client_.get(),
94                            module_system);
95   }
96
97   module_system->Initialize();
98 }
99
100 void XWalkExtensionRendererController::WillReleaseScriptContext(
101     blink::WebFrame* frame, v8::Handle<v8::Context> context) {
102   v8::Context::Scope contextScope(context);
103   XWalkModuleSystem::ResetModuleSystemFromContext(context);
104 }
105
106 bool XWalkExtensionRendererController::OnControlMessageReceived(
107     const IPC::Message& message) {
108   return in_browser_process_extensions_client_->OnMessageReceived(message);
109 }
110
111 void XWalkExtensionRendererController::OnRenderProcessShutdown() {
112   shutdown_event_.Signal();
113 }
114
115 void XWalkExtensionRendererController::SetupBrowserProcessClient(
116     IPC::SyncChannel* browser_channel) {
117   in_browser_process_extensions_client_.reset(new XWalkExtensionClient);
118   in_browser_process_extensions_client_->Initialize(browser_channel);
119 }
120
121 void XWalkExtensionRendererController::SetupExtensionProcessClient(
122     IPC::SyncChannel* browser_channel) {
123   IPC::ChannelHandle handle;
124   browser_channel->Send(
125       new XWalkExtensionProcessHostMsg_GetExtensionProcessChannel(&handle));
126   // FIXME(cmarcelo): Need to account for failure in creating the channel.
127
128   external_extensions_client_.reset(new XWalkExtensionClient);
129   extension_process_channel_ = IPC::SyncChannel::Create(handle,
130       IPC::Channel::MODE_CLIENT, external_extensions_client_.get(),
131       content::RenderThread::Get()->GetIOMessageLoopProxy(), true,
132       &shutdown_event_);
133
134   external_extensions_client_->Initialize(extension_process_channel_.get());
135 }
136
137
138 }  // namespace extensions
139 }  // namespace xwalk