15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/ppapi_proxy_test.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sstream>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind_helpers.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/observer_list.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/run_loop.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_sync_channel.h"
1534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#include "ipc/message_filter.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_errors.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/private/ppb_proxy_private.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/ppapi_messages.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/proxy/ppb_message_loop_proxy.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/shared_impl/proxy_lock.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ppapi {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace proxy {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HostDispatcher requires a PPB_Proxy_Private, so we always provide a fallback
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// do-nothing implementation.
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginCrashed(PP_Module module) {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Instance GetInstanceForResource(PP_Resource resource) {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If a test relies on this, we need to implement it.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetReserveInstanceIDCallback(PP_Module module,
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  PP_Bool (*is_seen)(PP_Module, PP_Instance)) {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This function gets called in HostDispatcher's constructor.  We simply don't
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // worry about Instance uniqueness in tests, so we can ignore the call.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddRefModule(PP_Module module) {}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReleaseModule(PP_Module module) {}
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Bool IsInModuleDestructor(PP_Module module) { return PP_FALSE; }
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_Proxy_Private ppb_proxy_private = {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  &PluginCrashed,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  &GetInstanceForResource,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  &SetReserveInstanceIDCallback,
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  &AddRefModule,
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  &ReleaseModule,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  &IsInModuleDestructor
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We allow multiple harnesses at a time to respond to 'GetInterface' calls.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We assume that only 1 harness's GetInterface function will ever support a
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// given interface name. In practice, there will either be only 1 GetInterface
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// handler (for PluginProxyTest or HostProxyTest), or there will be only 2
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// GetInterface handlers (for TwoWayTest).  In the latter case, one handler is
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for the PluginProxyTestHarness and should only respond for PPP interfaces,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and the other handler is for the HostProxyTestHarness which should only
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ever respond for PPB interfaces.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ObserverList<ProxyTestHarnessBase> get_interface_handlers_;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const void* MockGetInterface(const char* name) {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ObserverList<ProxyTestHarnessBase>::Iterator it =
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      get_interface_handlers_;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (ProxyTestHarnessBase* observer = it.GetNext()) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const void* interface = observer->GetInterface(name);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (interface)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return interface;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (strcmp(name, PPB_PROXY_PRIVATE_INTERFACE) == 0)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return &ppb_proxy_private;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetUpRemoteHarness(ProxyTestHarnessBase* harness,
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const IPC::ChannelHandle& handle,
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        base::MessageLoopProxy* ipc_message_loop_proxy,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        base::WaitableEvent* shutdown_event,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        base::WaitableEvent* harness_set_up) {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  harness->SetUpHarnessWithChannel(handle, ipc_message_loop_proxy,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   shutdown_event, false);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  harness_set_up->Signal();
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TearDownRemoteHarness(ProxyTestHarnessBase* harness,
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           base::WaitableEvent* harness_torn_down) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  harness->TearDownHarness();
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  harness_torn_down->Signal();
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RunTaskOnRemoteHarness(const base::Closure& task,
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            base::WaitableEvent* task_complete) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) task.Run();
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) task_complete->Signal();
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ProxyTestHarnessBase --------------------------------------------------------
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyTestHarnessBase::ProxyTestHarnessBase() : pp_module_(0x98765),
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               pp_instance_(0x12345) {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  get_interface_handlers_.AddObserver(this);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyTestHarnessBase::~ProxyTestHarnessBase() {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  get_interface_handlers_.RemoveObserver(this);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const void* ProxyTestHarnessBase::GetInterface(const char* name) {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return registered_interfaces_[name];
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ProxyTestHarnessBase::RegisterTestInterface(const char* name,
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 const void* test_interface) {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registered_interfaces_[name] = test_interface;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProxyTestHarnessBase::SupportsInterface(const char* name) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sink().ClearMessages();
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // IPC doesn't actually write to this when we send a message manually
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not actually using IPC.
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool unused_result = false;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PpapiMsg_SupportsInterface msg(name, &unused_result);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetDispatcher()->OnMessageReceived(msg);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const IPC::Message* reply_msg =
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sink().GetUniqueMessageMatching(IPC_REPLY_ID);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(reply_msg);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!reply_msg)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TupleTypes<PpapiMsg_SupportsInterface::ReplyParam>::ValueTuple reply_data;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(PpapiMsg_SupportsInterface::ReadReplyParam(
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reply_msg, &reply_data));
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sink().ClearMessages();
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return reply_data.a;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PluginProxyTestHarness ------------------------------------------------------
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PluginProxyTestHarness::PluginProxyTestHarness(
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GlobalsConfiguration globals_config)
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : globals_config_(globals_config) {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PluginProxyTestHarness::~PluginProxyTestHarness() {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PpapiGlobals* PluginProxyTestHarness::GetGlobals() {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return plugin_globals_.get();
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Dispatcher* PluginProxyTestHarness::GetDispatcher() {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return plugin_dispatcher_.get();
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginProxyTestHarness::SetUpHarness() {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These must be first since the dispatcher set-up uses them.
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CreatePluginGlobals();
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Some of the methods called during set-up check that the lock is held.
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ProxyAutoLock lock;
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resource_tracker().DidCreateInstance(pp_instance());
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  plugin_dispatcher_.reset(new PluginDispatcher(
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &MockGetInterface,
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PpapiPermissions(),
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false));
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  plugin_dispatcher_->InitWithTestSink(&sink());
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The plugin proxy delegate is needed for
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |PluginProxyDelegate::GetBrowserSender| which is used
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in |ResourceCreationProxy::GetConnection| to get the channel to the
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // browser. In this case we just use the |plugin_dispatcher_| as the channel
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for test purposes.
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  plugin_delegate_mock_.set_browser_sender(plugin_dispatcher_.get());
1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  PluginGlobals::Get()->SetPluginProxyDelegate(&plugin_delegate_mock_);
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  plugin_dispatcher_->DidCreateInstance(pp_instance());
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginProxyTestHarness::SetUpHarnessWithChannel(
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const IPC::ChannelHandle& channel_handle,
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::MessageLoopProxy* ipc_message_loop,
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::WaitableEvent* shutdown_event,
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_client) {
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These must be first since the dispatcher set-up uses them.
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CreatePluginGlobals();
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Some of the methods called during set-up check that the lock is held.
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ProxyAutoLock lock;
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resource_tracker().DidCreateInstance(pp_instance());
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  plugin_delegate_mock_.Init(ipc_message_loop, shutdown_event);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  plugin_dispatcher_.reset(new PluginDispatcher(
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &MockGetInterface,
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PpapiPermissions(),
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false));
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  plugin_dispatcher_->InitPluginWithChannel(&plugin_delegate_mock_,
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            base::kNullProcessId,
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            channel_handle,
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            is_client);
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  plugin_delegate_mock_.set_browser_sender(plugin_dispatcher_.get());
2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  PluginGlobals::Get()->SetPluginProxyDelegate(&plugin_delegate_mock_);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  plugin_dispatcher_->DidCreateInstance(pp_instance());
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginProxyTestHarness::TearDownHarness() {
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  {
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Some of the methods called during tear-down check that the lock is held.
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ProxyAutoLock lock;
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    plugin_dispatcher_->DidDestroyInstance(pp_instance());
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    plugin_dispatcher_.reset();
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    resource_tracker().DidDeleteInstance(pp_instance());
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  plugin_globals_.reset();
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PluginProxyTestHarness::CreatePluginGlobals() {
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (globals_config_ == PER_THREAD_GLOBALS) {
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    plugin_globals_.reset(new PluginGlobals(PpapiGlobals::PerThreadForTest()));
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PpapiGlobals::SetPpapiGlobalsOnThreadForTest(GetGlobals());
231d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // Enable locking in case some other unit test ran before us and disabled
232d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // locking.
233d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ProxyLock::EnableLockingOnThreadForTest();
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    plugin_globals_.reset(new PluginGlobals());
236d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ProxyLock::EnableLockingOnThreadForTest();
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::MessageLoopProxy*
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PluginProxyTestHarness::PluginDelegateMock::GetIPCMessageLoop() {
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ipc_message_loop_;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::WaitableEvent*
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PluginProxyTestHarness::PluginDelegateMock::GetShutdownEvent() {
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return shutdown_event_;
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IPC::PlatformFileForTransit
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PluginProxyTestHarness::PluginDelegateMock::ShareHandleWithRemote(
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PlatformFile handle,
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::ProcessId /* remote_pid */,
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool should_close_source) {
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return IPC::GetFileHandleForProcess(handle,
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      base::Process::Current().handle(),
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      should_close_source);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::set<PP_Instance>*
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PluginProxyTestHarness::PluginDelegateMock::GetGloballySeenInstanceIDSet() {
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return &instance_id_set_;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32 PluginProxyTestHarness::PluginDelegateMock::Register(
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PluginDispatcher* plugin_dispatcher) {
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginProxyTestHarness::PluginDelegateMock::Unregister(
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32 plugin_dispatcher_id) {
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IPC::Sender* PluginProxyTestHarness::PluginDelegateMock::GetBrowserSender() {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return browser_sender_;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string PluginProxyTestHarness::PluginDelegateMock::GetUILanguage() {
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return std::string("en-US");
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginProxyTestHarness::PluginDelegateMock::PreCacheFont(
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const void* logfontw) {
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginProxyTestHarness::PluginDelegateMock::SetActiveURL(
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& url) {
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben MurdochPP_Resource PluginProxyTestHarness::PluginDelegateMock::CreateBrowserFont(
29158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    Connection connection,
29258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    PP_Instance instance,
29358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    const PP_BrowserFont_Trusted_Description& desc,
29458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    const Preferences& prefs) {
29558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch  return 0;
29658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch}
29758e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PluginProxyTest -------------------------------------------------------------
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PluginProxyTest::PluginProxyTest() : PluginProxyTestHarness(SINGLETON_GLOBALS) {
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PluginProxyTest::~PluginProxyTest() {
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginProxyTest::SetUp() {
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetUpHarness();
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginProxyTest::TearDown() {
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TearDownHarness();
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// PluginProxyMultiThreadTest --------------------------------------------------
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PluginProxyMultiThreadTest::PluginProxyMultiThreadTest() {
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PluginProxyMultiThreadTest::~PluginProxyMultiThreadTest() {
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PluginProxyMultiThreadTest::RunTest() {
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  main_thread_message_loop_proxy_ =
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PpapiGlobals::Get()->GetMainThreadMessageLoop();
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(main_thread_message_loop_proxy_.get(),
3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            base::MessageLoopProxy::current().get());
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  nested_main_thread_message_loop_.reset(new base::RunLoop());
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  secondary_thread_.reset(new base::DelegateSimpleThread(
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      this, "PluginProxyMultiThreadTest"));
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ProxyAutoLock auto_lock;
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // MessageLoopResource assumes that the proxy lock has been acquired.
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    secondary_thread_message_loop_ = new MessageLoopResource(pp_instance());
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_EQ(PP_OK,
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        secondary_thread_message_loop_->PostWork(
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            PP_MakeCompletionCallback(
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                &PluginProxyMultiThreadTest::InternalSetUpTestOnSecondaryThread,
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                this),
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            0));
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUpTestOnMainThread();
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  secondary_thread_->Start();
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  nested_main_thread_message_loop_->Run();
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  secondary_thread_->Join();
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ProxyAutoLock auto_lock;
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The destruction requires a valid PpapiGlobals instance, so we should
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // explicitly release it.
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    secondary_thread_message_loop_ = NULL;
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  secondary_thread_.reset(NULL);
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  nested_main_thread_message_loop_.reset(NULL);
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  main_thread_message_loop_proxy_ = NULL;
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PluginProxyMultiThreadTest::CheckOnThread(ThreadType thread_type) {
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ProxyAutoLock auto_lock;
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (thread_type == MAIN_THREAD) {
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(MessageLoopResource::GetCurrent()->is_main_thread_loop());
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_EQ(secondary_thread_message_loop_.get(),
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              MessageLoopResource::GetCurrent());
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PluginProxyMultiThreadTest::PostQuitForMainThread() {
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  main_thread_message_loop_proxy_->PostTask(
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&PluginProxyMultiThreadTest::QuitNestedLoop,
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Unretained(this)));
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PluginProxyMultiThreadTest::PostQuitForSecondaryThread() {
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ProxyAutoLock auto_lock;
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  secondary_thread_message_loop_->PostQuit(PP_TRUE);
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PluginProxyMultiThreadTest::Run() {
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ProxyAutoLock auto_lock;
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(PP_OK, secondary_thread_message_loop_->AttachToCurrentThread());
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(PP_OK, secondary_thread_message_loop_->Run());
3917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  secondary_thread_message_loop_->DetachFromThread();
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PluginProxyMultiThreadTest::QuitNestedLoop() {
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  nested_main_thread_message_loop_->Quit();
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PluginProxyMultiThreadTest::InternalSetUpTestOnSecondaryThread(
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void* user_data,
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int32_t result) {
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(PP_OK, result);
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PluginProxyMultiThreadTest* thiz =
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      static_cast<PluginProxyMultiThreadTest*>(user_data);
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  thiz->CheckOnThread(SECONDARY_THREAD);
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  thiz->SetUpTestOnSecondaryThread();
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HostProxyTestHarness --------------------------------------------------------
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HostProxyTestHarness::HostProxyTestHarness(GlobalsConfiguration globals_config)
41234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    : globals_config_(globals_config) {
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HostProxyTestHarness::~HostProxyTestHarness() {
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PpapiGlobals* HostProxyTestHarness::GetGlobals() {
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return host_globals_.get();
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Dispatcher* HostProxyTestHarness::GetDispatcher() {
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return host_dispatcher_.get();
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HostProxyTestHarness::SetUpHarness() {
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These must be first since the dispatcher set-up uses them.
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CreateHostGlobals();
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_dispatcher_.reset(new HostDispatcher(
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pp_module(),
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &MockGetInterface,
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PpapiPermissions::AllPermissions()));
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_dispatcher_->InitWithTestSink(&sink());
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostDispatcher::SetForInstance(pp_instance(), host_dispatcher_.get());
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HostProxyTestHarness::SetUpHarnessWithChannel(
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const IPC::ChannelHandle& channel_handle,
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::MessageLoopProxy* ipc_message_loop,
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::WaitableEvent* shutdown_event,
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_client) {
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These must be first since the dispatcher set-up uses them.
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CreateHostGlobals();
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_mock_.Init(ipc_message_loop, shutdown_event);
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_dispatcher_.reset(new HostDispatcher(
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pp_module(),
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &MockGetInterface,
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PpapiPermissions::AllPermissions()));
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ppapi::Preferences preferences;
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  host_dispatcher_->InitHostWithChannel(&delegate_mock_,
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        base::kNullProcessId, channel_handle,
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        is_client, preferences);
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostDispatcher::SetForInstance(pp_instance(), host_dispatcher_.get());
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HostProxyTestHarness::TearDownHarness() {
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostDispatcher::RemoveForInstance(pp_instance());
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_dispatcher_.reset();
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_globals_.reset();
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HostProxyTestHarness::CreateHostGlobals() {
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (globals_config_ == PER_THREAD_GLOBALS) {
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    host_globals_.reset(new TestGlobals(PpapiGlobals::PerThreadForTest()));
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PpapiGlobals::SetPpapiGlobalsOnThreadForTest(GetGlobals());
469d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // The host side of the proxy does not lock.
470d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ProxyLock::DisableLockingOnThreadForTest();
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
472d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ProxyLock::DisableLockingOnThreadForTest();
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    host_globals_.reset(new TestGlobals());
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::MessageLoopProxy*
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HostProxyTestHarness::DelegateMock::GetIPCMessageLoop() {
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ipc_message_loop_;
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::WaitableEvent* HostProxyTestHarness::DelegateMock::GetShutdownEvent() {
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return shutdown_event_;
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IPC::PlatformFileForTransit
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HostProxyTestHarness::DelegateMock::ShareHandleWithRemote(
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PlatformFile handle,
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::ProcessId /* remote_pid */,
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool should_close_source) {
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return IPC::GetFileHandleForProcess(handle,
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      base::Process::Current().handle(),
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      should_close_source);
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HostProxyTest ---------------------------------------------------------------
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HostProxyTest::HostProxyTest() : HostProxyTestHarness(SINGLETON_GLOBALS) {
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HostProxyTest::~HostProxyTest() {
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HostProxyTest::SetUp() {
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetUpHarness();
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HostProxyTest::TearDown() {
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TearDownHarness();
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TwoWayTest ---------------------------------------------------------------
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TwoWayTest::TwoWayTest(TwoWayTest::TwoWayTestMode test_mode)
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : test_mode_(test_mode),
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      host_(ProxyTestHarnessBase::PER_THREAD_GLOBALS),
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      plugin_(ProxyTestHarnessBase::PER_THREAD_GLOBALS),
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      io_thread_("TwoWayTest_IOThread"),
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      plugin_thread_("TwoWayTest_PluginThread"),
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      remote_harness_(NULL),
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      local_harness_(NULL),
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      channel_created_(true, false),
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      shutdown_event_(true, false) {
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (test_mode == TEST_PPP_INTERFACE) {
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    remote_harness_ = &plugin_;
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    local_harness_ = &host_;
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    remote_harness_ = &host_;
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    local_harness_ = &plugin_;
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TwoWayTest::~TwoWayTest() {
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  shutdown_event_.Signal();
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TwoWayTest::SetUp() {
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Thread::Options options;
540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  options.message_loop_type = base::MessageLoop::TYPE_IO;
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io_thread_.StartWithOptions(options);
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  plugin_thread_.Start();
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Construct the IPC handle name using the process ID so we can safely run
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // multiple |TwoWayTest|s concurrently.
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::ostringstream handle_name;
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  handle_name << "TwoWayTestChannel" << base::GetCurrentProcId();
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC::ChannelHandle handle(handle_name.str());
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WaitableEvent remote_harness_set_up(true, false);
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  plugin_thread_.message_loop_proxy()->PostTask(
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&SetUpRemoteHarness,
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 remote_harness_,
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 handle,
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 io_thread_.message_loop_proxy(),
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 &shutdown_event_,
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 &remote_harness_set_up));
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  remote_harness_set_up.Wait();
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  local_harness_->SetUpHarnessWithChannel(handle,
5607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                          io_thread_.message_loop_proxy().get(),
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          &shutdown_event_,
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          true);  // is_client
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TwoWayTest::TearDown() {
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WaitableEvent remote_harness_torn_down(true, false);
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  plugin_thread_.message_loop_proxy()->PostTask(
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TearDownRemoteHarness,
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 remote_harness_,
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 &remote_harness_torn_down));
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  remote_harness_torn_down.Wait();
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  local_harness_->TearDownHarness();
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io_thread_.Stop();
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TwoWayTest::PostTaskOnRemoteHarness(const base::Closure& task) {
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WaitableEvent task_complete(true, false);
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  plugin_thread_.message_loop_proxy()->PostTask(FROM_HERE,
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&RunTaskOnRemoteHarness,
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 task,
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 &task_complete));
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  task_complete.Wait();
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace proxy
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ppapi
591