blob: 7bfacc52ec0c71862ce1d97aa82bf533f499af65 [file] [log] [blame]
[email protected]73097562012-01-12 19:38:551// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]f24448db2011-01-27 20:40:392// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ppapi/proxy/ppapi_proxy_test.h"
6
[email protected]1f6581c2011-10-04 23:10:157#include "base/bind.h"
[email protected]912f3d6c2011-06-29 18:26:368#include "base/message_loop_proxy.h"
9#include "base/observer_list.h"
10#include "ipc/ipc_sync_channel.h"
[email protected]f24448db2011-01-27 20:40:3911#include "ppapi/c/pp_errors.h"
[email protected]912f3d6c2011-06-29 18:26:3612#include "ppapi/c/private/ppb_proxy_private.h"
[email protected]465faa22011-02-08 16:31:4613#include "ppapi/proxy/ppapi_messages.h"
[email protected]f24448db2011-01-27 20:40:3914
[email protected]4d2efd22011-08-18 21:58:0215namespace ppapi {
[email protected]f24448db2011-01-27 20:40:3916namespace proxy {
17
18namespace {
[email protected]912f3d6c2011-06-29 18:26:3619// HostDispatcher requires a PPB_Proxy_Private, so we always provide a fallback
20// do-nothing implementation.
21void PluginCrashed(PP_Module module) {
22 NOTREACHED();
23};
[email protected]f24448db2011-01-27 20:40:3924
[email protected]912f3d6c2011-06-29 18:26:3625PP_Instance GetInstanceForResource(PP_Resource resource) {
26 // If a test relies on this, we need to implement it.
27 NOTREACHED();
28 return 0;
29}
30
31void SetReserveInstanceIDCallback(PP_Module module,
32 PP_Bool (*is_seen)(PP_Module, PP_Instance)) {
33 // This function gets called in HostDispatcher's constructor. We simply don't
34 // worry about Instance uniqueness in tests, so we can ignore the call.
35}
36
37int32_t GetURLLoaderBufferedBytes(PP_Resource url_loader) {
38 NOTREACHED();
39 return 0;
40}
41
42void AddRefModule(PP_Module module) {}
43void ReleaseModule(PP_Module module) {}
[email protected]fa4dd2912011-10-17 21:23:2944PP_Bool IsInModuleDestructor(PP_Module module) { return PP_FALSE; }
[email protected]912f3d6c2011-06-29 18:26:3645
[email protected]fa4dd2912011-10-17 21:23:2946PPB_Proxy_Private ppb_proxy_private = {
47 &PluginCrashed,
48 &GetInstanceForResource,
49 &SetReserveInstanceIDCallback,
50 &GetURLLoaderBufferedBytes,
51 &AddRefModule,
52 &ReleaseModule,
53 &IsInModuleDestructor
54};
[email protected]912f3d6c2011-06-29 18:26:3655
56// We allow multiple harnesses at a time to respond to 'GetInterface' calls.
57// We assume that only 1 harness's GetInterface function will ever support a
58// given interface name. In practice, there will either be only 1 GetInterface
59// handler (for PluginProxyTest or HostProxyTest), or there will be only 2
60// GetInterface handlers (for TwoWayTest). In the latter case, one handler is
61// for the PluginProxyTestHarness and should only respond for PPP interfaces,
62// and the other handler is for the HostProxyTestHarness which should only
63// ever respond for PPB interfaces.
64ObserverList<ProxyTestHarnessBase> get_interface_handlers_;
[email protected]465faa22011-02-08 16:31:4665
66const void* MockGetInterface(const char* name) {
[email protected]912f3d6c2011-06-29 18:26:3667 ObserverList<ProxyTestHarnessBase>::Iterator it =
68 get_interface_handlers_;
69 while (ProxyTestHarnessBase* observer = it.GetNext()) {
70 const void* interface = observer->GetInterface(name);
71 if (interface)
72 return interface;
[email protected]465faa22011-02-08 16:31:4673 }
[email protected]912f3d6c2011-06-29 18:26:3674 if (strcmp(name, PPB_PROXY_PRIVATE_INTERFACE) == 0)
75 return &ppb_proxy_private;
76 return NULL;
77}
78
79void SetUpRemoteHarness(ProxyTestHarnessBase* harness,
80 const IPC::ChannelHandle& handle,
81 base::MessageLoopProxy* ipc_message_loop_proxy,
82 base::WaitableEvent* shutdown_event,
83 base::WaitableEvent* harness_set_up) {
84 harness->SetUpHarnessWithChannel(handle, ipc_message_loop_proxy,
85 shutdown_event, false);
86 harness_set_up->Signal();
87}
88
89void TearDownRemoteHarness(ProxyTestHarnessBase* harness,
90 base::WaitableEvent* harness_torn_down) {
91 harness->TearDownHarness();
92 harness_torn_down->Signal();
[email protected]f24448db2011-01-27 20:40:3993}
94
[email protected]f24448db2011-01-27 20:40:3995} // namespace
96
[email protected]912f3d6c2011-06-29 18:26:3697// ProxyTestHarnessBase --------------------------------------------------------
[email protected]465faa22011-02-08 16:31:4698
[email protected]912f3d6c2011-06-29 18:26:3699ProxyTestHarnessBase::ProxyTestHarnessBase() : pp_module_(0x98765),
100 pp_instance_(0x12345) {
101 get_interface_handlers_.AddObserver(this);
[email protected]465faa22011-02-08 16:31:46102}
103
[email protected]912f3d6c2011-06-29 18:26:36104ProxyTestHarnessBase::~ProxyTestHarnessBase() {
105 get_interface_handlers_.RemoveObserver(this);
[email protected]465faa22011-02-08 16:31:46106}
107
[email protected]912f3d6c2011-06-29 18:26:36108const void* ProxyTestHarnessBase::GetInterface(const char* name) {
[email protected]465faa22011-02-08 16:31:46109 return registered_interfaces_[name];
110}
111
[email protected]912f3d6c2011-06-29 18:26:36112void ProxyTestHarnessBase::RegisterTestInterface(const char* name,
[email protected]99ff9932011-09-07 14:14:54113 const void* test_interface) {
114 registered_interfaces_[name] = test_interface;
[email protected]465faa22011-02-08 16:31:46115}
116
[email protected]912f3d6c2011-06-29 18:26:36117bool ProxyTestHarnessBase::SupportsInterface(const char* name) {
[email protected]465faa22011-02-08 16:31:46118 sink().ClearMessages();
119
120 // IPC doesn't actually write to this when we send a message manually
121 // not actually using IPC.
122 bool unused_result = false;
123 PpapiMsg_SupportsInterface msg(name, &unused_result);
124 GetDispatcher()->OnMessageReceived(msg);
125
126 const IPC::Message* reply_msg =
127 sink().GetUniqueMessageMatching(IPC_REPLY_ID);
128 EXPECT_TRUE(reply_msg);
129 if (!reply_msg)
130 return false;
131
132 TupleTypes<PpapiMsg_SupportsInterface::ReplyParam>::ValueTuple reply_data;
133 EXPECT_TRUE(PpapiMsg_SupportsInterface::ReadReplyParam(
134 reply_msg, &reply_data));
135
136 sink().ClearMessages();
137 return reply_data.a;
138}
139
[email protected]912f3d6c2011-06-29 18:26:36140// PluginProxyTestHarness ------------------------------------------------------
[email protected]465faa22011-02-08 16:31:46141
[email protected]73097562012-01-12 19:38:55142PluginProxyTestHarness::PluginProxyTestHarness()
143 : plugin_globals_(PpapiGlobals::ForTest()) {
[email protected]f24448db2011-01-27 20:40:39144}
145
[email protected]912f3d6c2011-06-29 18:26:36146PluginProxyTestHarness::~PluginProxyTestHarness() {
[email protected]f24448db2011-01-27 20:40:39147}
148
[email protected]912f3d6c2011-06-29 18:26:36149Dispatcher* PluginProxyTestHarness::GetDispatcher() {
[email protected]465faa22011-02-08 16:31:46150 return plugin_dispatcher_.get();
151}
152
[email protected]912f3d6c2011-06-29 18:26:36153void PluginProxyTestHarness::SetUpHarness() {
[email protected]f24448db2011-01-27 20:40:39154 // These must be first since the dispatcher set-up uses them.
[email protected]73097562012-01-12 19:38:55155 PpapiGlobals::SetPpapiGlobalsOnThreadForTest(GetGlobals());
[email protected]794d83cd2011-10-20 19:09:20156 resource_tracker().DidCreateInstance(pp_instance());
[email protected]f24448db2011-01-27 20:40:39157
[email protected]f24448db2011-01-27 20:40:39158 plugin_dispatcher_.reset(new PluginDispatcher(
159 base::Process::Current().handle(),
[email protected]a08ebea2011-02-13 17:50:20160 &MockGetInterface));
[email protected]465faa22011-02-08 16:31:46161 plugin_dispatcher_->InitWithTestSink(&sink());
162 plugin_dispatcher_->DidCreateInstance(pp_instance());
[email protected]f24448db2011-01-27 20:40:39163}
164
[email protected]912f3d6c2011-06-29 18:26:36165void PluginProxyTestHarness::SetUpHarnessWithChannel(
166 const IPC::ChannelHandle& channel_handle,
167 base::MessageLoopProxy* ipc_message_loop,
168 base::WaitableEvent* shutdown_event,
169 bool is_client) {
170 // These must be first since the dispatcher set-up uses them.
[email protected]73097562012-01-12 19:38:55171 PpapiGlobals::SetPpapiGlobalsOnThreadForTest(GetGlobals());
[email protected]794d83cd2011-10-20 19:09:20172 resource_tracker().DidCreateInstance(pp_instance());
[email protected]912f3d6c2011-06-29 18:26:36173 plugin_delegate_mock_.Init(ipc_message_loop, shutdown_event);
174
175 plugin_dispatcher_.reset(new PluginDispatcher(
176 base::Process::Current().handle(),
177 &MockGetInterface));
178 plugin_dispatcher_->InitPluginWithChannel(&plugin_delegate_mock_,
179 channel_handle,
180 is_client);
181 plugin_dispatcher_->DidCreateInstance(pp_instance());
182}
183
184void PluginProxyTestHarness::TearDownHarness() {
[email protected]465faa22011-02-08 16:31:46185 plugin_dispatcher_->DidDestroyInstance(pp_instance());
[email protected]f24448db2011-01-27 20:40:39186 plugin_dispatcher_.reset();
187
[email protected]794d83cd2011-10-20 19:09:20188 resource_tracker().DidDeleteInstance(pp_instance());
[email protected]f24448db2011-01-27 20:40:39189}
190
[email protected]912f3d6c2011-06-29 18:26:36191base::MessageLoopProxy*
192PluginProxyTestHarness::PluginDelegateMock::GetIPCMessageLoop() {
193 return ipc_message_loop_;
194}
195
196base::WaitableEvent*
197PluginProxyTestHarness::PluginDelegateMock::GetShutdownEvent() {
198 return shutdown_event_;
199}
200
201std::set<PP_Instance>*
202PluginProxyTestHarness::PluginDelegateMock::GetGloballySeenInstanceIDSet() {
203 return &instance_id_set_;
204}
205
[email protected]6fc87e02011-12-20 19:18:45206uint32 PluginProxyTestHarness::PluginDelegateMock::Register(
207 PluginDispatcher* plugin_dispatcher) {
208 return 0;
209}
210
211void PluginProxyTestHarness::PluginDelegateMock::Unregister(
212 uint32 plugin_dispatcher_id) {
213}
214
[email protected]912f3d6c2011-06-29 18:26:36215bool PluginProxyTestHarness::PluginDelegateMock::SendToBrowser(
216 IPC::Message* msg) {
217 NOTREACHED();
218 return false;
219}
220
[email protected]6fc87e02011-12-20 19:18:45221void PluginProxyTestHarness::PluginDelegateMock::PreCacheFont(
222 const void* logfontw) {
[email protected]373a95a2011-07-01 16:58:14223}
[email protected]7f801d82011-07-08 23:30:11224
[email protected]912f3d6c2011-06-29 18:26:36225// PluginProxyTest -------------------------------------------------------------
226
227PluginProxyTest::PluginProxyTest() {
228}
229
230PluginProxyTest::~PluginProxyTest() {
231}
232
233void PluginProxyTest::SetUp() {
234 SetUpHarness();
235}
236
237void PluginProxyTest::TearDown() {
238 TearDownHarness();
239}
240
241// HostProxyTestHarness --------------------------------------------------------
242
[email protected]73097562012-01-12 19:38:55243HostProxyTestHarness::HostProxyTestHarness()
244 : host_globals_(PpapiGlobals::ForTest()) {
[email protected]912f3d6c2011-06-29 18:26:36245}
246
247HostProxyTestHarness::~HostProxyTestHarness() {
248}
249
250Dispatcher* HostProxyTestHarness::GetDispatcher() {
251 return host_dispatcher_.get();
252}
253
254void HostProxyTestHarness::SetUpHarness() {
[email protected]73097562012-01-12 19:38:55255 // These must be first since the dispatcher set-up uses them.
256 PpapiGlobals::SetPpapiGlobalsOnThreadForTest(GetGlobals());
[email protected]912f3d6c2011-06-29 18:26:36257 host_dispatcher_.reset(new HostDispatcher(
258 base::Process::Current().handle(),
259 pp_module(),
260 &MockGetInterface));
261 host_dispatcher_->InitWithTestSink(&sink());
262 HostDispatcher::SetForInstance(pp_instance(), host_dispatcher_.get());
263}
264
265void HostProxyTestHarness::SetUpHarnessWithChannel(
266 const IPC::ChannelHandle& channel_handle,
267 base::MessageLoopProxy* ipc_message_loop,
268 base::WaitableEvent* shutdown_event,
269 bool is_client) {
[email protected]73097562012-01-12 19:38:55270 // These must be first since the dispatcher set-up uses them.
271 PpapiGlobals::SetPpapiGlobalsOnThreadForTest(GetGlobals());
[email protected]912f3d6c2011-06-29 18:26:36272 delegate_mock_.Init(ipc_message_loop, shutdown_event);
[email protected]73097562012-01-12 19:38:55273
[email protected]912f3d6c2011-06-29 18:26:36274 host_dispatcher_.reset(new HostDispatcher(
275 base::Process::Current().handle(),
276 pp_module(),
277 &MockGetInterface));
278 ppapi::Preferences preferences;
279 host_dispatcher_->InitHostWithChannel(&delegate_mock_, channel_handle,
280 is_client, preferences);
281 HostDispatcher::SetForInstance(pp_instance(), host_dispatcher_.get());
282}
283
284void HostProxyTestHarness::TearDownHarness() {
285 HostDispatcher::RemoveForInstance(pp_instance());
286 host_dispatcher_.reset();
287}
288
289base::MessageLoopProxy*
290HostProxyTestHarness::DelegateMock::GetIPCMessageLoop() {
291 return ipc_message_loop_;
292}
293
294base::WaitableEvent* HostProxyTestHarness::DelegateMock::GetShutdownEvent() {
295 return shutdown_event_;
296}
297
298
[email protected]465faa22011-02-08 16:31:46299// HostProxyTest ---------------------------------------------------------------
300
301HostProxyTest::HostProxyTest() {
302}
303
304HostProxyTest::~HostProxyTest() {
305}
306
[email protected]465faa22011-02-08 16:31:46307void HostProxyTest::SetUp() {
[email protected]912f3d6c2011-06-29 18:26:36308 SetUpHarness();
[email protected]465faa22011-02-08 16:31:46309}
310
311void HostProxyTest::TearDown() {
[email protected]912f3d6c2011-06-29 18:26:36312 TearDownHarness();
[email protected]465faa22011-02-08 16:31:46313}
314
[email protected]912f3d6c2011-06-29 18:26:36315// TwoWayTest ---------------------------------------------------------------
316
317TwoWayTest::TwoWayTest(TwoWayTest::TwoWayTestMode test_mode)
318 : test_mode_(test_mode),
319 io_thread_("TwoWayTest_IOThread"),
320 plugin_thread_("TwoWayTest_PluginThread"),
321 remote_harness_(NULL),
322 local_harness_(NULL),
323 channel_created_(true, false),
324 shutdown_event_(true, false) {
325 if (test_mode == TEST_PPP_INTERFACE) {
326 remote_harness_ = &plugin_;
327 local_harness_ = &host_;
328 } else {
329 remote_harness_ = &host_;
330 local_harness_ = &plugin_;
331 }
332}
333
334TwoWayTest::~TwoWayTest() {
335 shutdown_event_.Signal();
336}
337
338void TwoWayTest::SetUp() {
339 base::Thread::Options options;
340 options.message_loop_type = MessageLoop::TYPE_IO;
341 io_thread_.StartWithOptions(options);
342 plugin_thread_.Start();
343
344 IPC::ChannelHandle handle;
345 handle.name = "TwoWayTestChannel";
[email protected]912f3d6c2011-06-29 18:26:36346 base::WaitableEvent remote_harness_set_up(true, false);
347 plugin_thread_.message_loop_proxy()->PostTask(
348 FROM_HERE,
[email protected]1f6581c2011-10-04 23:10:15349 base::Bind(&SetUpRemoteHarness,
350 remote_harness_,
351 handle,
352 io_thread_.message_loop_proxy(),
353 &shutdown_event_,
354 &remote_harness_set_up));
[email protected]912f3d6c2011-06-29 18:26:36355 remote_harness_set_up.Wait();
356 local_harness_->SetUpHarnessWithChannel(handle,
357 io_thread_.message_loop_proxy(),
358 &shutdown_event_,
359 true); // is_client
360}
361
362void TwoWayTest::TearDown() {
363 base::WaitableEvent remote_harness_torn_down(true, false);
364 plugin_thread_.message_loop_proxy()->PostTask(
365 FROM_HERE,
[email protected]1f6581c2011-10-04 23:10:15366 base::Bind(&TearDownRemoteHarness,
367 remote_harness_,
368 &remote_harness_torn_down));
[email protected]912f3d6c2011-06-29 18:26:36369 remote_harness_torn_down.Wait();
370
371 local_harness_->TearDownHarness();
372
373 io_thread_.Stop();
374}
375
376
[email protected]f24448db2011-01-27 20:40:39377} // namespace proxy
[email protected]4d2efd22011-08-18 21:58:02378} // namespace ppapi