| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <cstring> |
| |
| #include "base/bind.h" |
| #include "base/synchronization/waitable_event.h" |
| #include "ppapi/c/pp_var.h" |
| #include "ppapi/c/ppb_var.h" |
| #include "ppapi/c/ppp_messaging.h" |
| #include "ppapi/proxy/ppapi_messages.h" |
| #include "ppapi/proxy/ppapi_proxy_test.h" |
| #include "ppapi/proxy/serialized_var.h" |
| #include "ppapi/shared_impl/api_id.h" |
| #include "ppapi/shared_impl/proxy_lock.h" |
| #include "ppapi/shared_impl/var.h" |
| |
| namespace ppapi { |
| namespace proxy { |
| |
| namespace { |
| |
| // This is an ad-hoc mock of PPP_Messaging using global variables. Eventually, |
| // generalize making PPAPI interface mocks by using IDL or macro/template magic. |
| PP_Instance received_instance; |
| PP_Var received_var; |
| base::WaitableEvent handle_message_called( |
| base::WaitableEvent::ResetPolicy::AUTOMATIC, |
| base::WaitableEvent::InitialState::NOT_SIGNALED); |
| |
| void HandleMessage(PP_Instance instance, PP_Var message_data) { |
| received_instance = instance; |
| received_var = message_data; |
| handle_message_called.Signal(); |
| } |
| |
| // Clear all the 'received' values for our mock. Call this before you expect |
| // one of the functions to be invoked. |
| void ResetReceived() { |
| received_instance = 0; |
| received_var.type = PP_VARTYPE_UNDEFINED; |
| received_var.value.as_id = 0; |
| } |
| |
| PPP_Messaging ppp_messaging_mock = { |
| &HandleMessage |
| }; |
| |
| // CallHandleMessage does the host-side work to cause HandleMessage to be called |
| // in the plugin side. |
| void CallHandleMessage(Dispatcher* dispatcher, |
| PP_Instance instance, |
| PP_Var message) { |
| dispatcher->Send(new PpapiMsg_PPPMessaging_HandleMessage( |
| API_ID_PPP_MESSAGING, |
| instance, |
| SerializedVarSendInputShmem(dispatcher, message, instance))); |
| } |
| |
| class PPP_Messaging_ProxyTest : public TwoWayTest { |
| public: |
| PPP_Messaging_ProxyTest() |
| : TwoWayTest(TwoWayTest::TEST_PPP_INTERFACE) { |
| plugin().RegisterTestInterface(PPP_MESSAGING_INTERFACE, |
| &ppp_messaging_mock); |
| } |
| }; |
| |
| void CompareAndReleaseStringVar(PluginProxyTestHarness* plugin_harness, |
| PP_Var received_var, |
| const std::string& test_string) { |
| ProxyAutoLock lock; |
| Var* received_string = plugin_harness->var_tracker().GetVar(received_var); |
| ASSERT_TRUE(received_string); |
| ASSERT_TRUE(received_string->AsStringVar()); |
| EXPECT_EQ(test_string, received_string->AsStringVar()->value()); |
| // Now release the var, and the string should go away (because the ref |
| // count should be one). |
| plugin_harness->var_tracker().ReleaseVar(received_var); |
| EXPECT_FALSE(StringVar::FromPPVar(received_var)); |
| } |
| |
| } // namespace |
| |
| TEST_F(PPP_Messaging_ProxyTest, SendMessages) { |
| PP_Instance expected_instance = pp_instance(); |
| PP_Var expected_var = PP_MakeUndefined(); |
| ResetReceived(); |
| Dispatcher* host_dispatcher = host().GetDispatcher(); |
| CallHandleMessage(host_dispatcher, expected_instance, expected_var); |
| handle_message_called.Wait(); |
| EXPECT_EQ(expected_instance, received_instance); |
| EXPECT_EQ(expected_var.type, received_var.type); |
| |
| expected_var = PP_MakeNull(); |
| ResetReceived(); |
| CallHandleMessage(host_dispatcher, expected_instance, expected_var); |
| handle_message_called.Wait(); |
| EXPECT_EQ(expected_instance, received_instance); |
| EXPECT_EQ(expected_var.type, received_var.type); |
| |
| expected_var = PP_MakeBool(PP_TRUE); |
| ResetReceived(); |
| CallHandleMessage(host_dispatcher, expected_instance, expected_var); |
| handle_message_called.Wait(); |
| EXPECT_EQ(expected_instance, received_instance); |
| EXPECT_EQ(expected_var.type, received_var.type); |
| EXPECT_EQ(expected_var.value.as_bool, received_var.value.as_bool); |
| |
| expected_var = PP_MakeInt32(12345); |
| ResetReceived(); |
| CallHandleMessage(host_dispatcher, expected_instance, expected_var); |
| handle_message_called.Wait(); |
| EXPECT_EQ(expected_instance, received_instance); |
| EXPECT_EQ(expected_var.type, received_var.type); |
| EXPECT_EQ(expected_var.value.as_int, received_var.value.as_int); |
| |
| expected_var = PP_MakeDouble(3.1415); |
| ResetReceived(); |
| CallHandleMessage(host_dispatcher, expected_instance, expected_var); |
| handle_message_called.Wait(); |
| EXPECT_EQ(expected_instance, received_instance); |
| EXPECT_EQ(expected_var.type, received_var.type); |
| EXPECT_EQ(expected_var.value.as_double, received_var.value.as_double); |
| |
| const std::string kTestString("Hello world!"); |
| expected_var = StringVar::StringToPPVar(kTestString); |
| ResetReceived(); |
| CallHandleMessage(host_dispatcher, expected_instance, expected_var); |
| // Now release the var, and the string should go away (because the ref |
| // count should be one). |
| host().var_tracker().ReleaseVar(expected_var); |
| EXPECT_FALSE(StringVar::FromPPVar(expected_var)); |
| |
| handle_message_called.Wait(); |
| EXPECT_EQ(expected_instance, received_instance); |
| EXPECT_EQ(expected_var.type, received_var.type); |
| PostTaskOnRemoteHarness( |
| base::Bind(CompareAndReleaseStringVar, |
| &plugin(), |
| received_var, |
| kTestString)); |
| } |
| |
| } // namespace proxy |
| } // namespace ppapi |
| |