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 namespace extensions {
30 const GURL kAboutBlankURL = GURL("about:blank");
32 XWalkExtensionRendererController::XWalkExtensionRendererController(
34 : shutdown_event_(false, false),
36 content::RenderThread* thread = content::RenderThread::Get();
37 thread->AddObserver(this);
38 IPC::SyncChannel* browser_channel = thread->GetChannel();
39 SetupBrowserProcessClient(browser_channel);
41 CommandLine* cmd_line = CommandLine::ForCurrentProcess();
42 if (cmd_line->HasSwitch(switches::kXWalkDisableExtensionProcess))
43 LOG(INFO) << "EXTENSION PROCESS DISABLED.";
45 SetupExtensionProcessClient(browser_channel);
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);
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())
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);
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);
81 module_system->RegisterNativeModule(
82 "v8tools", scoped_ptr<XWalkNativeModule>(new XWalkV8ToolsModule));
83 module_system->RegisterNativeModule(
84 "internal", CreateJSModuleFromResource(
85 IDR_XWALK_EXTENSIONS_INTERNAL_API));
87 delegate_->DidCreateModuleSystem(module_system);
89 CreateExtensionModules(in_browser_process_extensions_client_.get(),
92 if (external_extensions_client_) {
93 CreateExtensionModules(external_extensions_client_.get(),
97 module_system->Initialize();
100 void XWalkExtensionRendererController::WillReleaseScriptContext(
101 blink::WebFrame* frame, v8::Handle<v8::Context> context) {
102 v8::Context::Scope contextScope(context);
103 XWalkModuleSystem::ResetModuleSystemFromContext(context);
106 bool XWalkExtensionRendererController::OnControlMessageReceived(
107 const IPC::Message& message) {
108 return in_browser_process_extensions_client_->OnMessageReceived(message);
111 void XWalkExtensionRendererController::OnRenderProcessShutdown() {
112 shutdown_event_.Signal();
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);
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.
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,
134 external_extensions_client_->Initialize(extension_process_channel_.get());
138 } // namespace extensions