1 // Copyright (c) 2011 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.
5 #include "testing/gtest/include/gtest/gtest.h"
7 #include "base/compiler_specific.h"
8 #include "ppapi/shared_impl/proxy_lock.h"
9 #include "ppapi/shared_impl/var.h"
10 #include "ppapi/shared_impl/var_tracker.h"
11 #include "ppapi/shared_impl/test_globals.h"
17 int mock_var_alive_count
= 0;
19 class MockStringVar
: public StringVar
{
21 MockStringVar(const std::string
& str
) : StringVar(str
) {
22 mock_var_alive_count
++;
24 virtual ~MockStringVar() { mock_var_alive_count
--; }
25 bool HasValidVarID() { return GetExistingVarID() != 0; }
28 class MockObjectVar
: public Var
{
30 MockObjectVar() : Var() { mock_var_alive_count
++; }
31 virtual ~MockObjectVar() { mock_var_alive_count
--; }
32 virtual PP_VarType
GetType() const OVERRIDE
{ return PP_VARTYPE_OBJECT
; }
33 bool HasValidVarID() { return GetExistingVarID() != 0; }
38 class VarTrackerTest
: public testing::Test
{
42 // Test implementation.
43 virtual void SetUp() OVERRIDE
{
44 ASSERT_EQ(0, mock_var_alive_count
);
45 ProxyLock::EnableLockingOnThreadForTest();
47 virtual void TearDown() OVERRIDE
{}
49 VarTracker
& var_tracker() { return *globals_
.GetVarTracker(); }
55 // Test that ResetVarID is called when the last PP_Var ref was deleted but the
57 TEST_F(VarTrackerTest
, LastResourceRef
) {
59 scoped_refptr
<MockStringVar
> var(new MockStringVar(std::string("xyz")));
60 PP_Var pp_var
= var
->GetPPVar();
61 EXPECT_TRUE(var
->HasValidVarID());
62 EXPECT_TRUE(var_tracker().GetVar(var
->GetExistingVarID()));
64 // Releasing it should keep the object (because we have a ref) but reset the
66 EXPECT_TRUE(var_tracker().ReleaseVar(pp_var
));
67 EXPECT_FALSE(var
->HasValidVarID());
68 EXPECT_EQ(1, mock_var_alive_count
);
71 EXPECT_EQ(0, mock_var_alive_count
);
74 TEST_F(VarTrackerTest
, GetPluginRefAgain
) {
76 scoped_refptr
<MockStringVar
> var(new MockStringVar(std::string("xyz")));
77 PP_Var pp_var
= var
->GetPPVar();
78 EXPECT_TRUE(var_tracker().ReleaseVar(pp_var
));
79 EXPECT_FALSE(var
->HasValidVarID());
80 EXPECT_EQ(1, mock_var_alive_count
);
82 // Obtaining PP_Var ref again, and add ref from VarTracker.
83 pp_var
= var
->GetPPVar();
84 EXPECT_TRUE(var
->HasValidVarID());
85 EXPECT_TRUE(var_tracker().GetVar(var
->GetExistingVarID()));
86 scoped_refptr
<MockStringVar
> another_var
=
87 static_cast<MockStringVar
*>(var_tracker().GetVar(pp_var
));
88 EXPECT_EQ(1, mock_var_alive_count
);
90 // Releasing it again.
91 EXPECT_TRUE(var_tracker().ReleaseVar(pp_var
));
92 EXPECT_FALSE(var
->HasValidVarID());
93 EXPECT_EQ(1, mock_var_alive_count
);
96 EXPECT_FALSE(var_tracker().GetVar(pp_var
));
97 EXPECT_EQ(1, mock_var_alive_count
);
99 EXPECT_FALSE(var_tracker().GetVar(pp_var
));
100 EXPECT_EQ(0, mock_var_alive_count
);
103 // Tests when the plugin is holding a ref to a PP_Var when the instance is
104 // owned only by VarTracker.
105 TEST_F(VarTrackerTest
, PluginRefWithoutVarRef
) {
107 // Make a PP_Var with one ref held by the plugin, and release the reference.
108 scoped_refptr
<MockStringVar
> var(new MockStringVar(std::string("zzz")));
109 PP_Var pp_var
= var
->GetPPVar();
110 EXPECT_EQ(1, mock_var_alive_count
);
112 EXPECT_EQ(1, mock_var_alive_count
);
114 // The var is owned only by VarTracker. PP_Var must be still valid.
115 EXPECT_TRUE(var_tracker().GetVar(pp_var
));
117 var_tracker().ReleaseVar(pp_var
);
118 EXPECT_EQ(0, mock_var_alive_count
);
119 EXPECT_FALSE(var_tracker().GetVar(pp_var
));
122 // Tests on Var having type of PP_VARTYPE_OBJECT.
123 TEST_F(VarTrackerTest
, ObjectRef
) {
125 scoped_refptr
<MockObjectVar
> var(new MockObjectVar());
126 PP_Var pp_var
= var
->GetPPVar();
127 EXPECT_TRUE(var_tracker().ReleaseVar(pp_var
));
128 EXPECT_FALSE(var
->HasValidVarID());
129 EXPECT_EQ(1, mock_var_alive_count
);
131 // Obtaining PP_Var ref again, and add ref from VarTracker.
132 pp_var
= var
->GetPPVar();
133 EXPECT_TRUE(var
->HasValidVarID());
134 EXPECT_TRUE(var_tracker().GetVar(var
->GetExistingVarID()));
135 scoped_refptr
<MockObjectVar
> another_var
=
136 static_cast<MockObjectVar
*>(var_tracker().GetVar(pp_var
));
137 EXPECT_EQ(1, mock_var_alive_count
);
139 // Releasing all references, then only VarTracker own the instance.
141 EXPECT_TRUE(var_tracker().GetVar(pp_var
));
142 EXPECT_EQ(1, mock_var_alive_count
);
144 EXPECT_TRUE(var_tracker().GetVar(pp_var
));
145 EXPECT_EQ(1, mock_var_alive_count
);
147 // Releasing plugin reference.
148 EXPECT_TRUE(var_tracker().ReleaseVar(pp_var
));
149 EXPECT_EQ(0, mock_var_alive_count
);