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.
5 #include "testing/gtest/include/gtest/gtest.h"
7 #include "base/compiler_specific.h"
8 #include "base/message_loop/message_loop.h"
9 #include "ppapi/shared_impl/proxy_lock.h"
10 #include "ppapi/shared_impl/resource.h"
11 #include "ppapi/shared_impl/resource_tracker.h"
12 #include "ppapi/shared_impl/test_globals.h"
18 int mock_resource_alive_count
= 0;
19 int last_plugin_ref_was_deleted_count
= 0;
20 int instance_was_deleted_count
= 0;
22 class MyMockResource
: public Resource
{
24 MyMockResource(PP_Instance instance
) : Resource(OBJECT_IS_IMPL
, instance
) {
25 mock_resource_alive_count
++;
27 ~MyMockResource() override
{ mock_resource_alive_count
--; }
29 void LastPluginRefWasDeleted() override
{
30 last_plugin_ref_was_deleted_count
++;
32 void InstanceWasDeleted() override
{ instance_was_deleted_count
++; }
37 class ResourceTrackerTest
: public testing::Test
{
39 ResourceTrackerTest() {}
41 // Test implementation.
42 void SetUp() override
{
43 ASSERT_EQ(0, mock_resource_alive_count
);
44 last_plugin_ref_was_deleted_count
= 0;
45 instance_was_deleted_count
= 0;
47 void TearDown() override
{}
49 ResourceTracker
& resource_tracker() { return *globals_
.GetResourceTracker(); }
52 base::MessageLoop message_loop_
; // Required to receive callbacks.
56 // Test that LastPluginRefWasDeleted is called when the last plugin ref was
57 // deleted but the object lives on.
58 TEST_F(ResourceTrackerTest
, LastPluginRef
) {
59 PP_Instance instance
= 0x1234567;
61 resource_tracker().DidCreateInstance(instance
);
63 scoped_refptr
<MyMockResource
> resource(new MyMockResource(instance
));
64 PP_Resource pp_resource
= resource
->GetReference();
65 EXPECT_TRUE(resource_tracker().GetResource(pp_resource
));
67 // Releasing it should keep the object (because we have a ref) but fire the
68 // "last plugin ref" message.
69 resource_tracker().ReleaseResource(pp_resource
);
70 EXPECT_EQ(1, last_plugin_ref_was_deleted_count
);
71 EXPECT_EQ(1, mock_resource_alive_count
);
73 resource_tracker().DidDeleteInstance(instance
);
75 EXPECT_FALSE(resource_tracker().GetResource(pp_resource
));
78 // Tests when the plugin is holding a ref to a resource when the instance is
80 TEST_F(ResourceTrackerTest
, InstanceDeletedWithPluginRef
) {
81 // Make a resource with one ref held by the plugin, and delete the instance.
82 PP_Instance instance
= 0x2345678;
84 resource_tracker().DidCreateInstance(instance
);
85 MyMockResource
* resource
= new MyMockResource(instance
);
86 resource
->GetReference();
87 EXPECT_EQ(1, mock_resource_alive_count
);
88 resource_tracker().DidDeleteInstance(instance
);
90 // The resource should have been deleted, and before it was, it should have
91 // received a "last plugin ref was deleted" notification.
92 EXPECT_EQ(0, mock_resource_alive_count
);
93 EXPECT_EQ(1, last_plugin_ref_was_deleted_count
);
94 EXPECT_EQ(0, instance_was_deleted_count
);
97 // Test when the plugin and the internal implementation (via scoped_refptr) is
98 // holding a ref to a resource when the instance is deleted.
99 TEST_F(ResourceTrackerTest
, InstanceDeletedWithBothRefed
) {
100 // Create a new instance.
101 PP_Instance instance
= 0x3456789;
104 // Make a resource with one ref held by the plugin and one ref held by us
105 // (outlives the plugin), and delete the instance.
106 resource_tracker().DidCreateInstance(instance
);
107 scoped_refptr
<MyMockResource
> resource
= new MyMockResource(instance
);
108 resource
->GetReference();
109 EXPECT_EQ(1, mock_resource_alive_count
);
110 resource_tracker().DidDeleteInstance(instance
);
112 // The resource should NOT have been deleted, and it should have received both
113 // a "last plugin ref was deleted" and a "instance was deleted" notification.
114 EXPECT_EQ(1, mock_resource_alive_count
);
115 EXPECT_EQ(1, last_plugin_ref_was_deleted_count
);
116 EXPECT_EQ(1, instance_was_deleted_count
);
117 EXPECT_EQ(0, resource
->pp_instance());
120 EXPECT_EQ(0, mock_resource_alive_count
);