15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/ppapi_proxy_test.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/serialized_var.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/proxy_lock.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ppapi { 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace proxy { 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Var MakeObjectVar(int64_t object_id) { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var ret; 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret.type = PP_VARTYPE_OBJECT; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret.value.as_id = object_id; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ret; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SerializedVarTest : public PluginProxyTest { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SerializedVarTest() {} 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests output arguments in the plugin. This is when the host calls into the 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// plugin and the plugin returns something via an out param, like an exception. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SerializedVarTest, PluginSerializedVarInOutParam) { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyAutoLock lock; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var host_object = MakeObjectVar(0x31337); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var plugin_object; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Receive the object param, we should be tracking it with no refcount, and 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // no messages sent. 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SerializedVarTestConstructor input(host_object); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SerializedVarReceiveInput receive_input(input); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin_object = receive_input.Get(plugin_dispatcher()); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, var_tracker().GetRefCountForObject(plugin_object)); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0u, sink().message_count()); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SerializedVar sv; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The "OutParam" does its work in its destructor, it will write the 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // information to the SerializedVar we passed in the constructor. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SerializedVarOutParam out_param(&sv); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An out-param needs to pass a reference to the caller, so it's the 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // responsibility of the plugin to bump the ref-count on an input 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // parameter. 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var_tracker().AddRefVar(plugin_object); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object)); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should have informed the host that a reference was taken. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1u, sink().message_count()); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *out_param.OutParam(plugin_dispatcher()) = plugin_object; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The object should have transformed the plugin object back to the host 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // object ID. Nothing in the var tracker should have changed yet, and no 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // messages should have been sent. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SerializedVarTestReader reader(sv); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(host_object.value.as_id, reader.GetVar().value.as_id); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object)); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1u, sink().message_count()); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The out param should have done an "end receive caller owned" on the plugin 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // var serialization rules, which should have released the "track-with-no- 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reference" count in the var tracker as well as the 1 reference we passed 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // back to the host, so the object should no longer be in the tracker. The 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reference we added has been removed, so another message should be sent to 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the host to tell it we're done with the object. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_object)); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2u, sink().message_count()); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests output strings in the plugin. This is when the host calls into the 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// plugin with a string and the plugin returns it via an out param. 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SerializedVarTest, PluginSerializedStringVarInOutParam) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyAutoLock lock; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var plugin_string; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kTestString("elite"); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Receive the string param. We should track it with 1 refcount. 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SerializedVarTestConstructor input(kTestString); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SerializedVarReceiveInput receive_input(input); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin_string = receive_input.Get(plugin_dispatcher()); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_string)); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0u, sink().message_count()); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SerializedVar sv; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The "OutParam" does its work in its destructor, it will write the 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // information to the SerializedVar we passed in the constructor. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SerializedVarOutParam out_param(&sv); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An out-param needs to pass a reference to the caller, so it's the 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // responsibility of the plugin to bump the ref-count of an input 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // parameter. 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var_tracker().AddRefVar(plugin_string); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2, var_tracker().GetRefCountForObject(plugin_string)); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0u, sink().message_count()); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *out_param.OutParam(plugin_dispatcher()) = plugin_string; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The SerializedVar should have set the string value internally. Nothing in 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the var tracker should have changed yet, and no messages should have been 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // sent. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SerializedVarTestReader reader(sv); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) //EXPECT_EQ(kTestString, *reader.GetTrackerStringPtr()); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2, var_tracker().GetRefCountForObject(plugin_string)); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0u, sink().message_count()); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The reference the string had initially should be gone, and the reference we 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // passed to the host should also be gone, so the string should be removed. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_string)); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0u, sink().message_count()); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests receiving an argument and passing it back to the browser as an output 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// parameter. 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SerializedVarTest, PluginSerializedVarOutParam) { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyAutoLock lock; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var host_object = MakeObjectVar(0x31337); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start tracking this object in the plugin. 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var plugin_object = var_tracker().ReceiveObjectPassRef( 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host_object, plugin_dispatcher()); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object)); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SerializedVar sv; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The "OutParam" does its work in its destructor, it will write the 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // information to the SerializedVar we passed in the constructor. 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SerializedVarOutParam out_param(&sv); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *out_param.OutParam(plugin_dispatcher()) = plugin_object; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The object should have transformed the plugin object back to the host 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // object ID. Nothing in the var tracker should have changed yet, and no 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // messages should have been sent. 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SerializedVarTestReader reader(sv); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(host_object.value.as_id, reader.GetVar().value.as_id); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object)); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0u, sink().message_count()); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The out param should have done an "end send pass ref" on the plugin 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // var serialization rules, which should have in turn released the reference 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in the var tracker. Since we only had one reference, this should have sent 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a release to the browser. 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_object)); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1u, sink().message_count()); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't bother validating that message since it's nontrivial and the 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // PluginVarTracker test has cases that cover that this message is correct. 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests the case that the plugin receives the same var twice as an input 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// parameter (not passing ownership). 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SerializedVarTest, PluginReceiveInput) { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyAutoLock lock; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var host_object = MakeObjectVar(0x31337); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var plugin_object; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Receive the first param, we should be tracking it with no refcount, and 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // no messages sent. 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SerializedVarTestConstructor input1(host_object); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SerializedVarReceiveInput receive_input(input1); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin_object = receive_input.Get(plugin_dispatcher()); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, var_tracker().GetRefCountForObject(plugin_object)); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0u, sink().message_count()); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Receive the second param, it should be resolved to the same plugin 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // object and there should still be no refcount. 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SerializedVarTestConstructor input2(host_object); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SerializedVarReceiveInput receive_input2(input2); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var plugin_object2 = receive_input2.Get(plugin_dispatcher()); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(plugin_object.value.as_id, plugin_object2.value.as_id); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, var_tracker().GetRefCountForObject(plugin_object)); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0u, sink().message_count()); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Take a reference to the object, as if the plugin was using it, and then 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // release it, we should still be tracking the object since the 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ReceiveInputs keep the "track_with_no_reference_count" alive until 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // they're destroyed. 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var_tracker().AddRefVar(plugin_object); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object)); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var_tracker().ReleaseVar(plugin_object); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, var_tracker().GetRefCountForObject(plugin_object)); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2u, sink().message_count()); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since we didn't keep any refs to the objects, it should have freed the 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // object. 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_object)); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests the case that the plugin receives the same vars twice as an input 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// parameter (not passing ownership) within a vector. 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SerializedVarTest, PluginVectorReceiveInput) { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyAutoLock lock; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var host_object = MakeObjectVar(0x31337); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<PP_Var> plugin_objects; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<PP_Var> plugin_objects2; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Receive the params. The object should be tracked with no refcount and 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // no messages sent. The string should is plugin-side only and should have 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a reference-count of 1. 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SerializedVar> input1; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input1.push_back(SerializedVarTestConstructor(host_object)); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input1.push_back(SerializedVarTestConstructor("elite")); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SerializedVarVectorReceiveInput receive_input(input1); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t array_size = 0; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var* plugin_objects_array = 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) receive_input.Get(plugin_dispatcher(), &array_size); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin_objects.insert(plugin_objects.begin(), plugin_objects_array, 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin_objects_array + array_size); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(2u, array_size); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, var_tracker().GetRefCountForObject(plugin_objects[0])); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_objects[1])); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0u, sink().message_count()); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Receive the second param, it should be resolved to the same plugin 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // object and there should still be no refcount. 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SerializedVar> input2; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input2.push_back(SerializedVarTestConstructor(host_object)); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input2.push_back(SerializedVarTestConstructor("elite")); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SerializedVarVectorReceiveInput receive_input2(input2); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t array_size2 = 0; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var* plugin_objects_array2 = 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) receive_input2.Get(plugin_dispatcher(), &array_size2); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin_objects2.insert(plugin_objects2.begin(), plugin_objects_array2, 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin_objects_array2 + array_size2); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(2u, array_size2); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(plugin_objects[0].value.as_id, plugin_objects2[0].value.as_id); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, var_tracker().GetRefCountForObject(plugin_objects[0])); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Strings get re-created with a new ID. We don't try to reuse strings in 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the tracker, so the string should get a new ID. 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_NE(plugin_objects[1].value.as_id, plugin_objects2[1].value.as_id); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_objects2[1])); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0u, sink().message_count()); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Take a reference to the object, as if the plugin was using it, and then 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // release it, we should still be tracking the object since the 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ReceiveInputs keep the "track_with_no_reference_count" alive until 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // they're destroyed. 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var_tracker().AddRefVar(plugin_objects[0]); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_objects[0])); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var_tracker().ReleaseVar(plugin_objects[0]); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, var_tracker().GetRefCountForObject(plugin_objects[0])); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2u, sink().message_count()); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Take a reference to a string and then release it. Make sure no messages 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // are sent. 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t old_message_count = sink().message_count(); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var_tracker().AddRefVar(plugin_objects[1]); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2, var_tracker().GetRefCountForObject(plugin_objects[1])); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var_tracker().ReleaseVar(plugin_objects[1]); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_objects[1])); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(old_message_count, sink().message_count()); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since we didn't keep any refs to the objects or strings, so they should 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // have been freed. 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_objects[0])); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_objects[1])); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_objects2[1])); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests the plugin receiving a var as a return value from the browser 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// two different times (passing ownership). 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SerializedVarTest, PluginReceiveReturn) { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyAutoLock lock; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var host_object = MakeObjectVar(0x31337); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var plugin_object; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Receive the first param, we should be tracking it with a refcount of 1. 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SerializedVarTestConstructor input1(host_object); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReceiveSerializedVarReturnValue receive_input(input1); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin_object = receive_input.Return(plugin_dispatcher()); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object)); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0u, sink().message_count()); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Receive the second param, it should be resolved to the same plugin 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // object and there should be a plugin refcount of 2. There should have 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // been an IPC message sent that released the duplicated ref in the browser 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (so both of our refs are represented by one in the browser). 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SerializedVarTestConstructor input2(host_object); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReceiveSerializedVarReturnValue receive_input2(input2); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var plugin_object2 = receive_input2.Return(plugin_dispatcher()); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(plugin_object.value.as_id, plugin_object2.value.as_id); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2, var_tracker().GetRefCountForObject(plugin_object)); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1u, sink().message_count()); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The ReceiveSerializedVarReturnValue destructor shouldn't have affected 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the refcount or sent any messages. 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2, var_tracker().GetRefCountForObject(plugin_object)); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1u, sink().message_count()); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Manually release one refcount, it shouldn't have sent any more messages. 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var_tracker().ReleaseVar(plugin_object); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object)); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1u, sink().message_count()); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Manually release the last refcount, it should have freed it and sent a 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // release message to the browser. 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var_tracker().ReleaseVar(plugin_object); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_object)); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2u, sink().message_count()); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns a value from the browser to the plugin, then return that one ref 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// back to the browser. 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SerializedVarTest, PluginReturnValue) { 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProxyAutoLock lock; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var host_object = MakeObjectVar(0x31337); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var plugin_object; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Receive the param in the plugin. 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SerializedVarTestConstructor input1(host_object); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReceiveSerializedVarReturnValue receive_input(input1); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin_object = receive_input.Return(plugin_dispatcher()); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object)); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0u, sink().message_count()); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now return to the browser. 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SerializedVar output; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SerializedVarReturnValue return_output(&output); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return_output.Return(plugin_dispatcher(), plugin_object); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The ref in the plugin should be alive until the ReturnValue goes out of 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // scope, since the release needs to be after the browser processes the 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // message. 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object)); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When the ReturnValue object goes out of scope, it should have sent a 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // release message to the browser. 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_object)); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1u, sink().message_count()); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace proxy 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ppapi 355