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.
5 #include "xwalk/extensions/renderer/xwalk_extension_renderer_controller.h"
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"
28 #include "xwalk/application/common/constants.h"
32 namespace extensions {
34 const GURL kAboutBlankURL = GURL("about:blank");
36 XWalkExtensionRendererController::XWalkExtensionRendererController(
38 : shutdown_event_(false, false),
40 content::RenderThread* thread = content::RenderThread::Get();
41 thread->AddObserver(this);
42 IPC::SyncChannel* browser_channel = thread->GetChannel();
43 SetupBrowserProcessClient(browser_channel);
45 CommandLine* cmd_line = CommandLine::ForCurrentProcess();
46 if (cmd_line->HasSwitch(switches::kXWalkDisableExtensionProcess))
47 LOG(INFO) << "EXTENSION PROCESS DISABLED.";
49 SetupExtensionProcessClient(browser_channel);
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);
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())
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);
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)
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);
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);
103 module_system->RegisterNativeModule(
104 "v8tools", scoped_ptr<XWalkNativeModule>(new XWalkV8ToolsModule));
105 module_system->RegisterNativeModule(
106 "internal", CreateJSModuleFromResource(
107 IDR_XWALK_EXTENSIONS_INTERNAL_API));
109 delegate_->DidCreateModuleSystem(module_system);
111 CreateExtensionModules(in_browser_process_extensions_client_.get(),
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) &&
120 CreateExtensionModulesWithoutDeviceAPI(external_extensions_client_.get(),
123 CreateExtensionModules(external_extensions_client_.get(), module_system);
125 CreateExtensionModules(external_extensions_client_.get(),
130 module_system->Initialize();
133 void XWalkExtensionRendererController::WillReleaseScriptContext(
134 blink::WebLocalFrame* frame, v8::Handle<v8::Context> context) {
135 v8::Context::Scope contextScope(context);
136 XWalkModuleSystem::ResetModuleSystemFromContext(context);
139 bool XWalkExtensionRendererController::OnControlMessageReceived(
140 const IPC::Message& message) {
141 return in_browser_process_extensions_client_->OnMessageReceived(message);
144 void XWalkExtensionRendererController::OnRenderProcessShutdown() {
145 shutdown_event_.Signal();
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);
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.
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,
167 external_extensions_client_->Initialize(extension_process_channel_.get());
171 } // namespace extensions