Home | History | Annotate | Download | only in proxy
      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
      3 // found in the LICENSE file.
      4 
      5 #include <cstring>
      6 
      7 #include "base/synchronization/waitable_event.h"
      8 #include "ppapi/c/pp_var.h"
      9 #include "ppapi/c/ppb_var.h"
     10 #include "ppapi/c/ppp_messaging.h"
     11 #include "ppapi/proxy/ppapi_messages.h"
     12 #include "ppapi/proxy/ppapi_proxy_test.h"
     13 #include "ppapi/proxy/serialized_var.h"
     14 #include "ppapi/shared_impl/api_id.h"
     15 #include "ppapi/shared_impl/proxy_lock.h"
     16 #include "ppapi/shared_impl/var.h"
     17 
     18 namespace ppapi {
     19 namespace proxy {
     20 
     21 namespace {
     22 
     23 // This is a poor man's mock of PPP_Messaging using global variables. Eventually
     24 // we should generalize making PPAPI interface mocks by using IDL or macro/
     25 // template magic.
     26 PP_Instance received_instance;
     27 PP_Var received_var;
     28 base::WaitableEvent handle_message_called(false, false);
     29 
     30 void HandleMessage(PP_Instance instance, PP_Var message_data) {
     31   received_instance = instance;
     32   received_var = message_data;
     33   handle_message_called.Signal();
     34 }
     35 
     36 // Clear all the 'received' values for our mock.  Call this before you expect
     37 // one of the functions to be invoked.
     38 void ResetReceived() {
     39   received_instance = 0;
     40   received_var.type = PP_VARTYPE_UNDEFINED;
     41   received_var.value.as_id = 0;
     42 }
     43 
     44 PPP_Messaging ppp_messaging_mock = {
     45   &HandleMessage
     46 };
     47 
     48 // CallHandleMessage does the host-side work to cause HandleMessage to be called
     49 // in the plugin side.
     50 void CallHandleMessage(Dispatcher* dispatcher,
     51                        PP_Instance instance,
     52                        PP_Var message) {
     53   dispatcher->Send(new PpapiMsg_PPPMessaging_HandleMessage(
     54       API_ID_PPP_MESSAGING,
     55       instance,
     56       SerializedVarSendInputShmem(dispatcher, message, instance)));
     57 }
     58 
     59 class PPP_Messaging_ProxyTest : public TwoWayTest {
     60  public:
     61   PPP_Messaging_ProxyTest()
     62       : TwoWayTest(TwoWayTest::TEST_PPP_INTERFACE) {
     63     plugin().RegisterTestInterface(PPP_MESSAGING_INTERFACE,
     64                                    &ppp_messaging_mock);
     65   }
     66 };
     67 
     68 void CompareAndReleaseStringVar(PluginProxyTestHarness* plugin_harness,
     69                                 PP_Var received_var,
     70                                 const std::string& test_string) {
     71   ProxyAutoLock lock;
     72   Var* received_string = plugin_harness->var_tracker().GetVar(received_var);
     73   ASSERT_TRUE(received_string);
     74   ASSERT_TRUE(received_string->AsStringVar());
     75   EXPECT_EQ(test_string, received_string->AsStringVar()->value());
     76   // Now release the var, and the string should go away (because the ref
     77   // count should be one).
     78   plugin_harness->var_tracker().ReleaseVar(received_var);
     79   EXPECT_FALSE(StringVar::FromPPVar(received_var));
     80 }
     81 
     82 }  // namespace
     83 
     84 TEST_F(PPP_Messaging_ProxyTest, SendMessages) {
     85   PP_Instance expected_instance = pp_instance();
     86   PP_Var expected_var = PP_MakeUndefined();
     87   ResetReceived();
     88   Dispatcher* host_dispatcher = host().GetDispatcher();
     89   CallHandleMessage(host_dispatcher, expected_instance, expected_var);
     90   handle_message_called.Wait();
     91   EXPECT_EQ(expected_instance, received_instance);
     92   EXPECT_EQ(expected_var.type, received_var.type);
     93 
     94   expected_var = PP_MakeNull();
     95   ResetReceived();
     96   CallHandleMessage(host_dispatcher, expected_instance, expected_var);
     97   handle_message_called.Wait();
     98   EXPECT_EQ(expected_instance, received_instance);
     99   EXPECT_EQ(expected_var.type, received_var.type);
    100 
    101   expected_var = PP_MakeBool(PP_TRUE);
    102   ResetReceived();
    103   CallHandleMessage(host_dispatcher, expected_instance, expected_var);
    104   handle_message_called.Wait();
    105   EXPECT_EQ(expected_instance, received_instance);
    106   EXPECT_EQ(expected_var.type, received_var.type);
    107   EXPECT_EQ(expected_var.value.as_bool, received_var.value.as_bool);
    108 
    109   expected_var = PP_MakeInt32(12345);
    110   ResetReceived();
    111   CallHandleMessage(host_dispatcher, expected_instance, expected_var);
    112   handle_message_called.Wait();
    113   EXPECT_EQ(expected_instance, received_instance);
    114   EXPECT_EQ(expected_var.type, received_var.type);
    115   EXPECT_EQ(expected_var.value.as_int, received_var.value.as_int);
    116 
    117   expected_var = PP_MakeDouble(3.1415);
    118   ResetReceived();
    119   CallHandleMessage(host_dispatcher, expected_instance, expected_var);
    120   handle_message_called.Wait();
    121   EXPECT_EQ(expected_instance, received_instance);
    122   EXPECT_EQ(expected_var.type, received_var.type);
    123   EXPECT_EQ(expected_var.value.as_double, received_var.value.as_double);
    124 
    125   const std::string kTestString("Hello world!");
    126   expected_var = StringVar::StringToPPVar(kTestString);
    127   ResetReceived();
    128   CallHandleMessage(host_dispatcher, expected_instance, expected_var);
    129   // Now release the var, and the string should go away (because the ref
    130   // count should be one).
    131   host().var_tracker().ReleaseVar(expected_var);
    132   EXPECT_FALSE(StringVar::FromPPVar(expected_var));
    133 
    134   handle_message_called.Wait();
    135   EXPECT_EQ(expected_instance, received_instance);
    136   EXPECT_EQ(expected_var.type, received_var.type);
    137   PostTaskOnRemoteHarness(
    138       base::Bind(CompareAndReleaseStringVar,
    139                  &plugin(),
    140                  received_var,
    141                  kTestString));
    142 }
    143 
    144 }  // namespace proxy
    145 }  // namespace ppapi
    146 
    147