OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <map> | 5 #include <map> |
6 #include <set> | 6 #include <set> |
7 | 7 |
8 #include "build/build_config.h" | 8 #include "build/build_config.h" |
9 // Need to include this before most other files because it defines | 9 // Need to include this before most other files because it defines |
10 // IPC_MESSAGE_LOG_ENABLED. We need to use it to define | 10 // IPC_MESSAGE_LOG_ENABLED. We need to use it to define |
11 // IPC_MESSAGE_MACROS_LOG_ENABLED so ppapi_messages.h will generate the | 11 // IPC_MESSAGE_MACROS_LOG_ENABLED so ppapi_messages.h will generate the |
12 // ViewMsgLog et al. functions. | 12 // ViewMsgLog et al. functions. |
13 | 13 |
14 #include "base/message_loop.h" | 14 #include "base/message_loop.h" |
15 #include "base/synchronization/waitable_event.h" | 15 #include "base/synchronization/waitable_event.h" |
16 #include "base/threading/thread.h" | 16 #include "base/threading/thread.h" |
17 #include "ipc/ipc_channel_handle.h" | 17 #include "ipc/ipc_channel_handle.h" |
18 #include "ipc/ipc_logging.h" | 18 #include "ipc/ipc_logging.h" |
19 #include "ipc/ipc_message.h" | 19 #include "ipc/ipc_message.h" |
20 #include "native_client/src/shared/ppapi_proxy/ppruntime.h" | 20 #include "native_client/src/shared/ppapi_proxy/ppruntime.h" |
21 #include "native_client/src/untrusted/irt/irt_ppapi.h" | 21 #include "native_client/src/untrusted/irt/irt_ppapi.h" |
22 #include "ppapi/c/ppp.h" | 22 #include "ppapi/c/ppp.h" |
23 #include "ppapi/c/ppp_instance.h" | 23 #include "ppapi/c/ppp_instance.h" |
24 #include "ppapi/proxy/plugin_dispatcher.h" | 24 #include "ppapi/proxy/plugin_dispatcher.h" |
25 #include "ppapi/proxy/plugin_globals.h" | 25 #include "ppapi/proxy/plugin_globals.h" |
| 26 #include "ppapi/proxy/plugin_proxy_delegate.h" |
26 #include "ppapi/shared_impl/ppb_audio_shared.h" | 27 #include "ppapi/shared_impl/ppb_audio_shared.h" |
27 | 28 |
28 #if defined(IPC_MESSAGE_LOG_ENABLED) | 29 #if defined(IPC_MESSAGE_LOG_ENABLED) |
29 #define IPC_MESSAGE_MACROS_LOG_ENABLED | 30 #define IPC_MESSAGE_MACROS_LOG_ENABLED |
30 #include "ppapi/proxy/ppapi_messages.h" | 31 #include "ppapi/proxy/ppapi_messages.h" |
31 #endif | 32 #endif |
32 | 33 |
33 // This must match up with NACL_CHROME_INITIAL_IPC_DESC, | 34 // This must match up with NACL_CHROME_INITIAL_IPC_DESC, |
34 // defined in sel_main_chrome.h | 35 // defined in sel_main_chrome.h |
35 #define NACL_IPC_FD 6 | 36 #define NACL_IPC_FD 6 |
36 | 37 |
37 using ppapi::proxy::PluginDispatcher; | 38 using ppapi::proxy::PluginDispatcher; |
38 using ppapi::proxy::PluginGlobals; | 39 using ppapi::proxy::PluginGlobals; |
| 40 using ppapi::proxy::PluginProxyDelegate; |
| 41 using ppapi::proxy::ProxyChannel; |
| 42 using ppapi::proxy::SerializedHandle; |
39 | 43 |
40 namespace { | 44 namespace { |
41 | 45 |
42 // Copied from src/content/ppapi_plugin/ppapi_thread. This is a minimal | 46 // This class manages communication between the plugin and the browser, and |
43 // implementation to get us started. | 47 // manages the PluginDispatcher instances for communication between the plugin |
44 class PluginDispatcherDelegate : public PluginDispatcher::PluginDelegate { | 48 // and the renderer. |
| 49 class PpapiDispatcher : public ProxyChannel, |
| 50 public PluginDispatcher::PluginDelegate, |
| 51 public PluginProxyDelegate { |
45 public: | 52 public: |
46 explicit PluginDispatcherDelegate( | 53 explicit PpapiDispatcher(scoped_refptr<base::MessageLoopProxy> io_loop); |
47 scoped_refptr<base::MessageLoopProxy> io_loop) | |
48 : message_loop_(io_loop), | |
49 shutdown_event_(true, false) { | |
50 } | |
51 | 54 |
52 virtual base::MessageLoopProxy* GetIPCMessageLoop() OVERRIDE { | 55 // PluginDispatcher::PluginDelegate implementation. |
53 return message_loop_.get(); | 56 virtual base::MessageLoopProxy* GetIPCMessageLoop() OVERRIDE; |
54 } | 57 virtual base::WaitableEvent* GetShutdownEvent() OVERRIDE; |
55 | |
56 virtual base::WaitableEvent* GetShutdownEvent() OVERRIDE { | |
57 return &shutdown_event_; | |
58 } | |
59 | |
60 virtual IPC::PlatformFileForTransit ShareHandleWithRemote( | 58 virtual IPC::PlatformFileForTransit ShareHandleWithRemote( |
61 base::PlatformFile handle, | 59 base::PlatformFile handle, |
62 const IPC::SyncChannel& channel, | 60 const IPC::SyncChannel& channel, |
63 bool should_close_source) OVERRIDE { | 61 bool should_close_source) OVERRIDE; |
64 return IPC::InvalidPlatformFileForTransit(); | 62 virtual std::set<PP_Instance>* GetGloballySeenInstanceIDSet() OVERRIDE; |
65 } | 63 virtual uint32 Register(PluginDispatcher* plugin_dispatcher) OVERRIDE; |
| 64 virtual void Unregister(uint32 plugin_dispatcher_id) OVERRIDE; |
66 | 65 |
67 virtual std::set<PP_Instance>* GetGloballySeenInstanceIDSet() OVERRIDE { | 66 // PluginProxyDelegate implementation. |
68 return &instances_; | 67 virtual bool SendToBrowser(IPC::Message* msg) OVERRIDE; |
69 } | 68 virtual IPC::Sender* GetBrowserSender() OVERRIDE; |
| 69 virtual std::string GetUILanguage() OVERRIDE; |
| 70 virtual void PreCacheFont(const void* logfontw) OVERRIDE; |
| 71 virtual void SetActiveURL(const std::string& url) OVERRIDE; |
70 | 72 |
71 virtual uint32 Register(PluginDispatcher* plugin_dispatcher) OVERRIDE { | 73 // IPC::Listener implementation. |
72 if (!plugin_dispatcher || | 74 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; |
73 plugin_dispatchers_.size() >= std::numeric_limits<uint32>::max()) { | |
74 return 0; | |
75 } | |
76 | |
77 uint32 id = 0; | |
78 do { | |
79 // Although it is unlikely, make sure that we won't cause any trouble when | |
80 // the counter overflows. | |
81 id = next_plugin_dispatcher_id_++; | |
82 } while (id == 0 || | |
83 plugin_dispatchers_.find(id) != plugin_dispatchers_.end()); | |
84 plugin_dispatchers_[id] = plugin_dispatcher; | |
85 return id; | |
86 } | |
87 | |
88 virtual void Unregister(uint32 plugin_dispatcher_id) OVERRIDE { | |
89 plugin_dispatchers_.erase(plugin_dispatcher_id); | |
90 } | |
91 | 75 |
92 private: | 76 private: |
| 77 void OnMsgCreateNaClChannel(int renderer_id, |
| 78 bool incognito, |
| 79 SerializedHandle handle); |
| 80 void OnPluginDispatcherMessageReceived(const IPC::Message& msg); |
| 81 |
93 std::set<PP_Instance> instances_; | 82 std::set<PP_Instance> instances_; |
94 std::map<uint32, PluginDispatcher*> plugin_dispatchers_; | 83 std::map<uint32, PluginDispatcher*> plugin_dispatchers_; |
95 uint32 next_plugin_dispatcher_id_; | 84 uint32 next_plugin_dispatcher_id_; |
96 scoped_refptr<base::MessageLoopProxy> message_loop_; | 85 scoped_refptr<base::MessageLoopProxy> message_loop_; |
97 base::WaitableEvent shutdown_event_; | 86 base::WaitableEvent shutdown_event_; |
98 }; | 87 }; |
99 | 88 |
| 89 PpapiDispatcher::PpapiDispatcher(scoped_refptr<base::MessageLoopProxy> io_loop) |
| 90 : message_loop_(io_loop), |
| 91 shutdown_event_(true, false) { |
| 92 IPC::ChannelHandle channel_handle( |
| 93 "NaCl IPC", base::FileDescriptor(NACL_IPC_FD, false)); |
| 94 InitWithChannel(this, channel_handle, false); // Channel is server. |
| 95 } |
| 96 |
| 97 base::MessageLoopProxy* PpapiDispatcher::GetIPCMessageLoop() { |
| 98 return message_loop_.get(); |
| 99 } |
| 100 |
| 101 base::WaitableEvent* PpapiDispatcher::GetShutdownEvent() { |
| 102 return &shutdown_event_; |
| 103 } |
| 104 |
| 105 IPC::PlatformFileForTransit PpapiDispatcher::ShareHandleWithRemote( |
| 106 base::PlatformFile handle, |
| 107 const IPC::SyncChannel& channel, |
| 108 bool should_close_source) { |
| 109 return IPC::InvalidPlatformFileForTransit(); |
| 110 } |
| 111 |
| 112 std::set<PP_Instance>* PpapiDispatcher::GetGloballySeenInstanceIDSet() { |
| 113 return &instances_; |
| 114 } |
| 115 |
| 116 uint32 PpapiDispatcher::Register(PluginDispatcher* plugin_dispatcher) { |
| 117 if (!plugin_dispatcher || |
| 118 plugin_dispatchers_.size() >= std::numeric_limits<uint32>::max()) { |
| 119 return 0; |
| 120 } |
| 121 |
| 122 uint32 id = 0; |
| 123 do { |
| 124 // Although it is unlikely, make sure that we won't cause any trouble |
| 125 // when the counter overflows. |
| 126 id = next_plugin_dispatcher_id_++; |
| 127 } while (id == 0 || |
| 128 plugin_dispatchers_.find(id) != plugin_dispatchers_.end()); |
| 129 plugin_dispatchers_[id] = plugin_dispatcher; |
| 130 return id; |
| 131 } |
| 132 |
| 133 void PpapiDispatcher::Unregister(uint32 plugin_dispatcher_id) { |
| 134 plugin_dispatchers_.erase(plugin_dispatcher_id); |
| 135 } |
| 136 |
| 137 bool PpapiDispatcher::SendToBrowser(IPC::Message* msg) { |
| 138 Send(msg); |
| 139 } |
| 140 |
| 141 IPC::Sender* PpapiDispatcher::GetBrowserSender() { |
| 142 return this; |
| 143 } |
| 144 |
| 145 std::string PpapiDispatcher::GetUILanguage() { |
| 146 NOTIMPLEMENTED(); |
| 147 return std::string(); |
| 148 } |
| 149 |
| 150 void PpapiDispatcher::PreCacheFont(const void* logfontw) { |
| 151 NOTIMPLEMENTED(); |
| 152 } |
| 153 |
| 154 void PpapiDispatcher::SetActiveURL(const std::string& url) { |
| 155 NOTIMPLEMENTED(); |
| 156 } |
| 157 |
| 158 bool PpapiDispatcher::OnMessageReceived(const IPC::Message& msg) { |
| 159 IPC_BEGIN_MESSAGE_MAP(PpapiDispatcher, msg) |
| 160 IPC_MESSAGE_HANDLER(PpapiMsg_CreateNaClChannel, |
| 161 OnMsgCreateNaClChannel) |
| 162 IPC_END_MESSAGE_MAP() |
| 163 return true; |
| 164 } |
| 165 |
| 166 void PpapiDispatcher::OnMsgCreateNaClChannel(int renderer_id, |
| 167 bool incognito, |
| 168 SerializedHandle handle) { |
| 169 PluginDispatcher* dispatcher = |
| 170 new PluginDispatcher(::PPP_GetInterface, incognito); |
| 171 // The channel handle's true name is not revealed here. |
| 172 IPC::ChannelHandle channel_handle("nacl", handle.descriptor()); |
| 173 if (!dispatcher->InitPluginWithChannel(this, channel_handle, false)) { |
| 174 delete dispatcher; |
| 175 return; |
| 176 } |
| 177 // From here, the dispatcher will manage its own lifetime according to the |
| 178 // lifetime of the attached channel. |
| 179 } |
| 180 |
| 181 void PpapiDispatcher::OnPluginDispatcherMessageReceived( |
| 182 const IPC::Message& msg) { |
| 183 // The first parameter should be a plugin dispatcher ID. |
| 184 PickleIterator iter(msg); |
| 185 uint32 id = 0; |
| 186 if (!msg.ReadUInt32(&iter, &id)) { |
| 187 NOTREACHED(); |
| 188 return; |
| 189 } |
| 190 std::map<uint32, ppapi::proxy::PluginDispatcher*>::iterator dispatcher = |
| 191 plugin_dispatchers_.find(id); |
| 192 if (dispatcher != plugin_dispatchers_.end()) |
| 193 dispatcher->second->OnMessageReceived(msg); |
| 194 } |
| 195 |
100 } // namespace | 196 } // namespace |
101 | 197 |
102 void PpapiPluginRegisterThreadCreator( | 198 void PpapiPluginRegisterThreadCreator( |
103 const struct PP_ThreadFunctions* thread_functions) { | 199 const struct PP_ThreadFunctions* thread_functions) { |
104 // Initialize all classes that need to create threads that call back into | 200 // Initialize all classes that need to create threads that call back into |
105 // user code. | 201 // user code. |
106 ppapi::PPB_Audio_Shared::SetThreadFunctions(thread_functions); | 202 ppapi::PPB_Audio_Shared::SetThreadFunctions(thread_functions); |
107 } | 203 } |
108 | 204 |
109 int IrtInit() { | 205 int IrtInit() { |
(...skipping 10 matching lines...) Expand all Loading... |
120 options.message_loop_type = MessageLoop::TYPE_IO; | 216 options.message_loop_type = MessageLoop::TYPE_IO; |
121 io_thread.StartWithOptions(options); | 217 io_thread.StartWithOptions(options); |
122 | 218 |
123 int32_t error = ::PPP_InitializeModule( | 219 int32_t error = ::PPP_InitializeModule( |
124 0 /* module */, | 220 0 /* module */, |
125 &ppapi::proxy::PluginDispatcher::GetBrowserInterface); | 221 &ppapi::proxy::PluginDispatcher::GetBrowserInterface); |
126 // TODO(dmichael): Handle other error conditions, like failure to connect? | 222 // TODO(dmichael): Handle other error conditions, like failure to connect? |
127 if (error) | 223 if (error) |
128 return error; | 224 return error; |
129 | 225 |
130 PluginDispatcherDelegate delegate(io_thread.message_loop_proxy()); | 226 PpapiDispatcher ppapi_dispatcher(io_thread.message_loop_proxy()); |
131 | |
132 // TODO(dmichael) Figure out how to determine if we're in incognito | |
133 PluginDispatcher dispatcher(::PPP_GetInterface, false /* incognito */); | |
134 IPC::ChannelHandle channel_handle("NaCl IPC", | |
135 base::FileDescriptor(NACL_IPC_FD, false)); | |
136 dispatcher.InitPluginWithChannel(&delegate, channel_handle, false); | |
137 | 227 |
138 loop.Run(); | 228 loop.Run(); |
139 return 0; | 229 return 0; |
140 } | 230 } |
141 | 231 |
OLD | NEW |