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 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. 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: 47 PPP_Messaging_ProxyTest() 48 : TwoWayTest(TwoWayTest::TEST_PPP_INTERFACE) { 49 plugin().RegisterTestInterface(PPP_MESSAGING_INTERFACE, 50 &ppp_messaging_mock); 51 } 52 }; 53 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 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