| Index: ppapi/proxy/ppapi_proxy_test.cc
|
| diff --git a/ppapi/proxy/ppapi_proxy_test.cc b/ppapi/proxy/ppapi_proxy_test.cc
|
| index 17823025ab8e3368625695f313a17edb92814b4b..733f04c5483423715db40e285dcca1044f6aff4d 100644
|
| --- a/ppapi/proxy/ppapi_proxy_test.cc
|
| +++ b/ppapi/proxy/ppapi_proxy_test.cc
|
| @@ -4,48 +4,113 @@
|
|
|
| #include "ppapi/proxy/ppapi_proxy_test.h"
|
|
|
| +#include "base/message_loop_proxy.h"
|
| +#include "base/observer_list.h"
|
| +#include "ipc/ipc_sync_channel.h"
|
| #include "ppapi/c/pp_errors.h"
|
| +#include "ppapi/c/private/ppb_proxy_private.h"
|
| #include "ppapi/proxy/ppapi_messages.h"
|
| +#include "ppapi/shared_impl/ppapi_preferences.cc"
|
|
|
| namespace pp {
|
| namespace proxy {
|
|
|
| namespace {
|
| +// HostDispatcher requires a PPB_Proxy_Private, so we always provide a fallback
|
| +// do-nothing implementation.
|
| +void PluginCrashed(PP_Module module) {
|
| + NOTREACHED();
|
| +};
|
| +
|
| +PP_Instance GetInstanceForResource(PP_Resource resource) {
|
| + // If a test relies on this, we need to implement it.
|
| + NOTREACHED();
|
| + return 0;
|
| +}
|
| +
|
| +void SetReserveInstanceIDCallback(PP_Module module,
|
| + PP_Bool (*is_seen)(PP_Module, PP_Instance)) {
|
| + // This function gets called in HostDispatcher's constructor. We simply don't
|
| + // worry about Instance uniqueness in tests, so we can ignore the call.
|
| +}
|
|
|
| -ProxyTestBase* current_test = NULL;
|
| +int32_t GetURLLoaderBufferedBytes(PP_Resource url_loader) {
|
| + NOTREACHED();
|
| + return 0;
|
| +}
|
| +
|
| +void AddRefModule(PP_Module module) {}
|
| +void ReleaseModule(PP_Module module) {}
|
| +
|
| +PPB_Proxy_Private ppb_proxy_private = { PluginCrashed,
|
| + GetInstanceForResource,
|
| + SetReserveInstanceIDCallback,
|
| + GetURLLoaderBufferedBytes,
|
| + AddRefModule,
|
| + ReleaseModule };
|
| +
|
| +// We allow multiple harnesses at a time to respond to 'GetInterface' calls.
|
| +// We assume that only 1 harness's GetInterface function will ever support a
|
| +// given interface name. In practice, there will either be only 1 GetInterface
|
| +// handler (for PluginProxyTest or HostProxyTest), or there will be only 2
|
| +// GetInterface handlers (for TwoWayTest). In the latter case, one handler is
|
| +// for the PluginProxyTestHarness and should only respond for PPP interfaces,
|
| +// and the other handler is for the HostProxyTestHarness which should only
|
| +// ever respond for PPB interfaces.
|
| +ObserverList<ProxyTestHarnessBase> get_interface_handlers_;
|
|
|
| const void* MockGetInterface(const char* name) {
|
| - if (!current_test) {
|
| - NOTREACHED();
|
| - return NULL;
|
| + ObserverList<ProxyTestHarnessBase>::Iterator it =
|
| + get_interface_handlers_;
|
| + while (ProxyTestHarnessBase* observer = it.GetNext()) {
|
| + const void* interface = observer->GetInterface(name);
|
| + if (interface)
|
| + return interface;
|
| }
|
| - return current_test->GetInterface(name);
|
| + if (strcmp(name, PPB_PROXY_PRIVATE_INTERFACE) == 0)
|
| + return &ppb_proxy_private;
|
| + return NULL;
|
| +}
|
| +
|
| +void SetUpRemoteHarness(ProxyTestHarnessBase* harness,
|
| + const IPC::ChannelHandle& handle,
|
| + base::MessageLoopProxy* ipc_message_loop_proxy,
|
| + base::WaitableEvent* shutdown_event,
|
| + base::WaitableEvent* harness_set_up) {
|
| + harness->SetUpHarnessWithChannel(handle, ipc_message_loop_proxy,
|
| + shutdown_event, false);
|
| + harness_set_up->Signal();
|
| +}
|
| +
|
| +void TearDownRemoteHarness(ProxyTestHarnessBase* harness,
|
| + base::WaitableEvent* harness_torn_down) {
|
| + harness->TearDownHarness();
|
| + harness_torn_down->Signal();
|
| }
|
|
|
| } // namespace
|
|
|
| -// ProxyTestBase ---------------------------------------------------------------
|
| +// ProxyTestHarnessBase --------------------------------------------------------
|
|
|
| -ProxyTestBase::ProxyTestBase() : pp_module_(0x98765), pp_instance_(0x12345) {
|
| - DCHECK(!current_test);
|
| - current_test = this;
|
| +ProxyTestHarnessBase::ProxyTestHarnessBase() : pp_module_(0x98765),
|
| + pp_instance_(0x12345) {
|
| + get_interface_handlers_.AddObserver(this);
|
| }
|
|
|
| -ProxyTestBase::~ProxyTestBase() {
|
| - DCHECK(current_test == this);
|
| - current_test = NULL;
|
| +ProxyTestHarnessBase::~ProxyTestHarnessBase() {
|
| + get_interface_handlers_.RemoveObserver(this);
|
| }
|
|
|
| -const void* ProxyTestBase::GetInterface(const char* name) {
|
| +const void* ProxyTestHarnessBase::GetInterface(const char* name) {
|
| return registered_interfaces_[name];
|
| }
|
|
|
| -void ProxyTestBase::RegisterTestInterface(const char* name,
|
| - const void* interface) {
|
| +void ProxyTestHarnessBase::RegisterTestInterface(const char* name,
|
| + const void* interface) {
|
| registered_interfaces_[name] = interface;
|
| }
|
|
|
| -bool ProxyTestBase::SupportsInterface(const char* name) {
|
| +bool ProxyTestHarnessBase::SupportsInterface(const char* name) {
|
| sink().ClearMessages();
|
|
|
| // IPC doesn't actually write to this when we send a message manually
|
| @@ -68,19 +133,19 @@ bool ProxyTestBase::SupportsInterface(const char* name) {
|
| return reply_data.a;
|
| }
|
|
|
| -// PluginProxyTest -------------------------------------------------------------
|
| +// PluginProxyTestHarness ------------------------------------------------------
|
|
|
| -PluginProxyTest::PluginProxyTest() {
|
| +PluginProxyTestHarness::PluginProxyTestHarness() {
|
| }
|
|
|
| -PluginProxyTest::~PluginProxyTest() {
|
| +PluginProxyTestHarness::~PluginProxyTestHarness() {
|
| }
|
|
|
| -Dispatcher* PluginProxyTest::GetDispatcher() {
|
| +Dispatcher* PluginProxyTestHarness::GetDispatcher() {
|
| return plugin_dispatcher_.get();
|
| }
|
|
|
| -void PluginProxyTest::SetUp() {
|
| +void PluginProxyTestHarness::SetUpHarness() {
|
| // These must be first since the dispatcher set-up uses them.
|
| PluginResourceTracker::SetInstanceForTest(&resource_tracker_);
|
| PluginVarTracker::SetInstanceForTest(&var_tracker_);
|
| @@ -92,7 +157,26 @@ void PluginProxyTest::SetUp() {
|
| plugin_dispatcher_->DidCreateInstance(pp_instance());
|
| }
|
|
|
| -void PluginProxyTest::TearDown() {
|
| +void PluginProxyTestHarness::SetUpHarnessWithChannel(
|
| + const IPC::ChannelHandle& channel_handle,
|
| + base::MessageLoopProxy* ipc_message_loop,
|
| + base::WaitableEvent* shutdown_event,
|
| + bool is_client) {
|
| + // These must be first since the dispatcher set-up uses them.
|
| + PluginResourceTracker::SetInstanceForTest(&resource_tracker_);
|
| + PluginVarTracker::SetInstanceForTest(&var_tracker_);
|
| + plugin_delegate_mock_.Init(ipc_message_loop, shutdown_event);
|
| +
|
| + plugin_dispatcher_.reset(new PluginDispatcher(
|
| + base::Process::Current().handle(),
|
| + &MockGetInterface));
|
| + plugin_dispatcher_->InitPluginWithChannel(&plugin_delegate_mock_,
|
| + channel_handle,
|
| + is_client);
|
| + plugin_dispatcher_->DidCreateInstance(pp_instance());
|
| +}
|
| +
|
| +void PluginProxyTestHarness::TearDownHarness() {
|
| plugin_dispatcher_->DidDestroyInstance(pp_instance());
|
| plugin_dispatcher_.reset();
|
|
|
| @@ -100,19 +184,68 @@ void PluginProxyTest::TearDown() {
|
| PluginResourceTracker::SetInstanceForTest(NULL);
|
| }
|
|
|
| -// HostProxyTest ---------------------------------------------------------------
|
| +base::MessageLoopProxy*
|
| +PluginProxyTestHarness::PluginDelegateMock::GetIPCMessageLoop() {
|
| + return ipc_message_loop_;
|
| +}
|
|
|
| -HostProxyTest::HostProxyTest() {
|
| +base::WaitableEvent*
|
| +PluginProxyTestHarness::PluginDelegateMock::GetShutdownEvent() {
|
| + return shutdown_event_;
|
| }
|
|
|
| -HostProxyTest::~HostProxyTest() {
|
| +std::set<PP_Instance>*
|
| +PluginProxyTestHarness::PluginDelegateMock::GetGloballySeenInstanceIDSet() {
|
| + return &instance_id_set_;
|
| +}
|
| +
|
| +ppapi::WebKitForwarding*
|
| +PluginProxyTestHarness::PluginDelegateMock::GetWebKitForwarding() {
|
| + NOTREACHED();
|
| + return NULL;
|
| +}
|
| +
|
| +void PluginProxyTestHarness::PluginDelegateMock::PostToWebKitThread(
|
| + const tracked_objects::Location& from_here, const base::Closure& task) {
|
| + NOTREACHED();
|
| +}
|
| +
|
| +bool PluginProxyTestHarness::PluginDelegateMock::SendToBrowser(
|
| + IPC::Message* msg) {
|
| + NOTREACHED();
|
| + return false;
|
| +}
|
| +
|
| +
|
| +// PluginProxyTest -------------------------------------------------------------
|
| +
|
| +PluginProxyTest::PluginProxyTest() {
|
| +}
|
| +
|
| +PluginProxyTest::~PluginProxyTest() {
|
| +}
|
| +
|
| +void PluginProxyTest::SetUp() {
|
| + SetUpHarness();
|
| +}
|
| +
|
| +void PluginProxyTest::TearDown() {
|
| + TearDownHarness();
|
| +}
|
| +
|
| +// HostProxyTestHarness --------------------------------------------------------
|
| +
|
| +HostProxyTestHarness::HostProxyTestHarness() {
|
| +}
|
| +
|
| +HostProxyTestHarness::~HostProxyTestHarness() {
|
| }
|
|
|
| -Dispatcher* HostProxyTest::GetDispatcher() {
|
| +Dispatcher* HostProxyTestHarness::GetDispatcher() {
|
| return host_dispatcher_.get();
|
| }
|
|
|
| -void HostProxyTest::SetUp() {
|
| +void HostProxyTestHarness::SetUpHarness() {
|
| host_dispatcher_.reset(new HostDispatcher(
|
| base::Process::Current().handle(),
|
| pp_module(),
|
| @@ -121,10 +254,115 @@ void HostProxyTest::SetUp() {
|
| HostDispatcher::SetForInstance(pp_instance(), host_dispatcher_.get());
|
| }
|
|
|
| -void HostProxyTest::TearDown() {
|
| +void HostProxyTestHarness::SetUpHarnessWithChannel(
|
| + const IPC::ChannelHandle& channel_handle,
|
| + base::MessageLoopProxy* ipc_message_loop,
|
| + base::WaitableEvent* shutdown_event,
|
| + bool is_client) {
|
| + delegate_mock_.Init(ipc_message_loop, shutdown_event);
|
| + host_dispatcher_.reset(new HostDispatcher(
|
| + base::Process::Current().handle(),
|
| + pp_module(),
|
| + &MockGetInterface));
|
| + ppapi::Preferences preferences;
|
| + host_dispatcher_->InitHostWithChannel(&delegate_mock_, channel_handle,
|
| + is_client, preferences);
|
| + HostDispatcher::SetForInstance(pp_instance(), host_dispatcher_.get());
|
| +}
|
| +
|
| +void HostProxyTestHarness::TearDownHarness() {
|
| HostDispatcher::RemoveForInstance(pp_instance());
|
| host_dispatcher_.reset();
|
| }
|
|
|
| +base::MessageLoopProxy*
|
| +HostProxyTestHarness::DelegateMock::GetIPCMessageLoop() {
|
| + return ipc_message_loop_;
|
| +}
|
| +
|
| +base::WaitableEvent* HostProxyTestHarness::DelegateMock::GetShutdownEvent() {
|
| + return shutdown_event_;
|
| +}
|
| +
|
| +
|
| +// HostProxyTest ---------------------------------------------------------------
|
| +
|
| +HostProxyTest::HostProxyTest() {
|
| +}
|
| +
|
| +HostProxyTest::~HostProxyTest() {
|
| +}
|
| +
|
| +void HostProxyTest::SetUp() {
|
| + SetUpHarness();
|
| +}
|
| +
|
| +void HostProxyTest::TearDown() {
|
| + TearDownHarness();
|
| +}
|
| +
|
| +// TwoWayTest ---------------------------------------------------------------
|
| +
|
| +TwoWayTest::TwoWayTest(TwoWayTest::TwoWayTestMode test_mode)
|
| + : test_mode_(test_mode),
|
| + io_thread_("TwoWayTest_IOThread"),
|
| + plugin_thread_("TwoWayTest_PluginThread"),
|
| + remote_harness_(NULL),
|
| + local_harness_(NULL),
|
| + channel_created_(true, false),
|
| + shutdown_event_(true, false) {
|
| + if (test_mode == TEST_PPP_INTERFACE) {
|
| + remote_harness_ = &plugin_;
|
| + local_harness_ = &host_;
|
| + } else {
|
| + remote_harness_ = &host_;
|
| + local_harness_ = &plugin_;
|
| + }
|
| +}
|
| +
|
| +TwoWayTest::~TwoWayTest() {
|
| + shutdown_event_.Signal();
|
| +}
|
| +
|
| +void TwoWayTest::SetUp() {
|
| + base::Thread::Options options;
|
| + options.message_loop_type = MessageLoop::TYPE_IO;
|
| + io_thread_.StartWithOptions(options);
|
| + plugin_thread_.Start();
|
| +
|
| + IPC::ChannelHandle handle;
|
| + handle.name = "TwoWayTestChannel";
|
| +
|
| + base::WaitableEvent remote_harness_set_up(true, false);
|
| + plugin_thread_.message_loop_proxy()->PostTask(
|
| + FROM_HERE,
|
| + NewRunnableFunction(&SetUpRemoteHarness,
|
| + remote_harness_,
|
| + handle,
|
| + io_thread_.message_loop_proxy(),
|
| + &shutdown_event_,
|
| + &remote_harness_set_up));
|
| + remote_harness_set_up.Wait();
|
| + local_harness_->SetUpHarnessWithChannel(handle,
|
| + io_thread_.message_loop_proxy(),
|
| + &shutdown_event_,
|
| + true); // is_client
|
| +}
|
| +
|
| +void TwoWayTest::TearDown() {
|
| + base::WaitableEvent remote_harness_torn_down(true, false);
|
| + plugin_thread_.message_loop_proxy()->PostTask(
|
| + FROM_HERE,
|
| + NewRunnableFunction(&TearDownRemoteHarness,
|
| + remote_harness_,
|
| + &remote_harness_torn_down));
|
| + remote_harness_torn_down.Wait();
|
| +
|
| + local_harness_->TearDownHarness();
|
| +
|
| + io_thread_.Stop();
|
| +}
|
| +
|
| +
|
| } // namespace proxy
|
| } // namespace pp
|
|
|