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 18namespace ppapi { 19namespace proxy { 20 21namespace { 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. 26PP_Instance received_instance; 27PP_Var received_var; 28base::WaitableEvent handle_message_called(false, false); 29 30void 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. 38void ResetReceived() { 39 received_instance = 0; 40 received_var.type = PP_VARTYPE_UNDEFINED; 41 received_var.value.as_id = 0; 42} 43 44PPP_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. 50void 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 59class 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 68void 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 84TEST_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