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