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/extension_process/xwalk_extension_process.h"
9 #include "base/command_line.h"
10 #include "base/files/file_path.h"
11 #include "base/message_loop/message_loop.h"
12 #include "ipc/ipc_switches.h"
13 #include "ipc/ipc_message_macros.h"
14 #include "ipc/ipc_sync_channel.h"
15 #include "xwalk/extensions/common/xwalk_extension_messages.h"
18 namespace extensions {
20 XWalkExtensionProcess::XWalkExtensionProcess()
21 : shutdown_event_(false, false),
22 io_thread_("XWalkExtensionProcess_IOThread") {
23 io_thread_.StartWithOptions(
24 base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
26 extensions_server_.set_permissions_delegate(this);
27 CreateBrowserProcessChannel();
30 XWalkExtensionProcess::~XWalkExtensionProcess() {
31 // FIXME(jeez): Move this to OnChannelClosing/Error/Disconnected when we have
32 // our MessageFilter set.
33 extensions_server_.Invalidate();
35 shutdown_event_.Signal();
39 bool XWalkExtensionProcess::OnMessageReceived(const IPC::Message& message) {
41 IPC_BEGIN_MESSAGE_MAP(XWalkExtensionProcess, message)
42 IPC_MESSAGE_HANDLER(XWalkExtensionProcessMsg_RegisterExtensions,
44 IPC_MESSAGE_UNHANDLED(handled = false)
51 void ToValueMap(base::ListValue* lv, base::ValueMap* vm) {
54 for (base::ListValue::iterator it = lv->begin(); it != lv->end(); it++) {
55 base::DictionaryValue* dv;
56 if (!(*it)->GetAsDictionary(&dv))
58 for (base::DictionaryValue::Iterator dit(*dv);
59 !dit.IsAtEnd(); dit.Advance())
60 (*vm)[dit.key()] = dit.value().DeepCopy();
66 void XWalkExtensionProcess::OnRegisterExtensions(
67 const base::FilePath& path, const base::ListValue& browser_variables_lv) {
69 base::ValueMap browser_variables;
71 ToValueMap(&const_cast<base::ListValue&>(browser_variables_lv),
74 RegisterExternalExtensionsInDirectory(&extensions_server_, path,
77 CreateRenderProcessChannel();
80 void XWalkExtensionProcess::CreateBrowserProcessChannel() {
81 std::string channel_id =
82 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
83 switches::kProcessChannelID);
84 browser_process_channel_.reset(new IPC::SyncChannel(channel_id,
85 IPC::Channel::MODE_CLIENT, this, io_thread_.message_loop_proxy(),
86 true, &shutdown_event_));
89 void XWalkExtensionProcess::CreateRenderProcessChannel() {
90 IPC::ChannelHandle handle(IPC::Channel::GenerateVerifiedChannelID(
92 rp_channel_handle_ = handle;
94 render_process_channel_.reset(new IPC::SyncChannel(rp_channel_handle_,
95 IPC::Channel::MODE_SERVER, &extensions_server_,
96 io_thread_.message_loop_proxy(), true, &shutdown_event_));
99 // On POSIX, pass the server-side file descriptor. We use
100 // TakeClientFileDescriptor() instead of GetClientFileDescriptor()
101 // since the client-side channel will take ownership of the fd.
102 rp_channel_handle_.socket =
103 base::FileDescriptor(render_process_channel_->TakeClientFileDescriptor(),
107 extensions_server_.Initialize(render_process_channel_.get());
109 browser_process_channel_->Send(
110 new XWalkExtensionProcessHostMsg_RenderProcessChannelCreated(
111 rp_channel_handle_));
114 bool XWalkExtensionProcess::CheckAPIAccessControl(
115 const std::string& extension_name,
116 const std::string& api_name) {
117 PermissionCacheType::iterator iter =
118 permission_cache_.find(extension_name + api_name);
119 if (iter != permission_cache_.end())
122 RuntimePermission result = UNDEFINED_RUNTIME_PERM;
123 browser_process_channel_->Send(
124 new XWalkExtensionProcessHostMsg_CheckAPIAccessControl(
125 extension_name, api_name, &result));
126 DLOG(INFO) << extension_name << "." << api_name << "() --> " << result;
127 if (result == ALLOW_SESSION ||
128 result == ALLOW_ALWAYS ||
129 result == DENY_SESSION ||
130 result == DENY_ALWAYS) {
131 permission_cache_[extension_name+api_name] = result;
132 return (result == ALLOW_SESSION || result == ALLOW_ALWAYS);
135 // Could be allow/deny once or undefined here.
136 return (result == ALLOW_ONCE);
139 bool XWalkExtensionProcess::RegisterPermissions(
140 const std::string& extension_name,
141 const std::string& perm_table) {
143 browser_process_channel_->Send(
144 new XWalkExtensionProcessHostMsg_RegisterPermissions(
145 extension_name, perm_table, &result));
149 } // namespace extensions