• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "testing/gtest/include/gtest/gtest.h"
6 
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"
12 
13 namespace ppapi {
14 
15 namespace {
16 
17 int mock_var_alive_count = 0;
18 
19 class MockStringVar : public StringVar {
20  public:
MockStringVar(const std::string & str)21   MockStringVar(const std::string& str) : StringVar(str) {
22     mock_var_alive_count++;
23   }
~MockStringVar()24   virtual ~MockStringVar() { mock_var_alive_count--; }
HasValidVarID()25   bool HasValidVarID() { return GetExistingVarID() != 0; }
26 };
27 
28 class MockObjectVar : public Var {
29  public:
MockObjectVar()30   MockObjectVar() : Var() { mock_var_alive_count++; }
~MockObjectVar()31   virtual ~MockObjectVar() { mock_var_alive_count--; }
GetType() const32   virtual PP_VarType GetType() const OVERRIDE { return PP_VARTYPE_OBJECT; }
HasValidVarID()33   bool HasValidVarID() { return GetExistingVarID() != 0; }
34 };
35 
36 }  // namespace
37 
38 class VarTrackerTest : public testing::Test {
39  public:
VarTrackerTest()40   VarTrackerTest() {}
41 
42   // Test implementation.
SetUp()43   virtual void SetUp() OVERRIDE {
44     ASSERT_EQ(0, mock_var_alive_count);
45     ProxyLock::EnableLockingOnThreadForTest();
46   }
TearDown()47   virtual void TearDown() OVERRIDE {}
48 
var_tracker()49   VarTracker& var_tracker() { return *globals_.GetVarTracker(); }
50 
51  private:
52   TestGlobals globals_;
53 };
54 
55 // Test that ResetVarID is called when the last PP_Var ref was deleted but the
56 // object lives on.
TEST_F(VarTrackerTest,LastResourceRef)57 TEST_F(VarTrackerTest, LastResourceRef) {
58   ProxyAutoLock lock;
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()));
63 
64   // Releasing it should keep the object (because we have a ref) but reset the
65   // var_id_.
66   EXPECT_TRUE(var_tracker().ReleaseVar(pp_var));
67   EXPECT_FALSE(var->HasValidVarID());
68   EXPECT_EQ(1, mock_var_alive_count);
69 
70   var = NULL;
71   EXPECT_EQ(0, mock_var_alive_count);
72 }
73 
TEST_F(VarTrackerTest,GetPluginRefAgain)74 TEST_F(VarTrackerTest, GetPluginRefAgain) {
75   ProxyAutoLock lock;
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);
81 
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);
89 
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);
94 
95   var = NULL;
96   EXPECT_FALSE(var_tracker().GetVar(pp_var));
97   EXPECT_EQ(1, mock_var_alive_count);
98   another_var = NULL;
99   EXPECT_FALSE(var_tracker().GetVar(pp_var));
100   EXPECT_EQ(0, mock_var_alive_count);
101 }
102 
103 // Tests when the plugin is holding a ref to a PP_Var when the instance is
104 // owned only by VarTracker.
TEST_F(VarTrackerTest,PluginRefWithoutVarRef)105 TEST_F(VarTrackerTest, PluginRefWithoutVarRef) {
106   ProxyAutoLock lock;
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);
111   var = NULL;
112   EXPECT_EQ(1, mock_var_alive_count);
113 
114   // The var is owned only by VarTracker. PP_Var must be still valid.
115   EXPECT_TRUE(var_tracker().GetVar(pp_var));
116 
117   var_tracker().ReleaseVar(pp_var);
118   EXPECT_EQ(0, mock_var_alive_count);
119   EXPECT_FALSE(var_tracker().GetVar(pp_var));
120 }
121 
122 // Tests on Var having type of PP_VARTYPE_OBJECT.
TEST_F(VarTrackerTest,ObjectRef)123 TEST_F(VarTrackerTest, ObjectRef) {
124   ProxyAutoLock lock;
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);
130 
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);
138 
139   // Releasing all references, then only VarTracker own the instance.
140   var = NULL;
141   EXPECT_TRUE(var_tracker().GetVar(pp_var));
142   EXPECT_EQ(1, mock_var_alive_count);
143   another_var = NULL;
144   EXPECT_TRUE(var_tracker().GetVar(pp_var));
145   EXPECT_EQ(1, mock_var_alive_count);
146 
147   // Releasing plugin reference.
148   EXPECT_TRUE(var_tracker().ReleaseVar(pp_var));
149   EXPECT_EQ(0, mock_var_alive_count);
150 }
151 
152 }  // namespace ppapi
153