• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
HandleMessage(PP_Instance instance,PP_Var message_data)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.
ResetReceived()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.
CallHandleMessage(Dispatcher * dispatcher,PP_Instance instance,PP_Var message)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:
PPP_Messaging_ProxyTest()61   PPP_Messaging_ProxyTest()
62       : TwoWayTest(TwoWayTest::TEST_PPP_INTERFACE) {
63     plugin().RegisterTestInterface(PPP_MESSAGING_INTERFACE,
64                                    &ppp_messaging_mock);
65   }
66 };
67 
CompareAndReleaseStringVar(PluginProxyTestHarness * plugin_harness,PP_Var received_var,const std::string & test_string)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 
TEST_F(PPP_Messaging_ProxyTest,SendMessages)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