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. 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/resource.h" 10 #include "ppapi/shared_impl/resource_tracker.h" 11 #include "ppapi/shared_impl/test_globals.h" 12 13 namespace ppapi { 14 15 namespace { 16 17 int mock_resource_alive_count = 0; 18 int last_plugin_ref_was_deleted_count = 0; 19 int instance_was_deleted_count = 0; 20 21 class MyMockResource : public Resource { 22 public: 23 MyMockResource(PP_Instance instance) : Resource(OBJECT_IS_IMPL, instance) { 24 mock_resource_alive_count++; 25 } 26 virtual ~MyMockResource() { 27 mock_resource_alive_count--; 28 } 29 30 virtual void LastPluginRefWasDeleted() OVERRIDE { 31 last_plugin_ref_was_deleted_count++; 32 } 33 virtual void InstanceWasDeleted() OVERRIDE { 34 instance_was_deleted_count++; 35 } 36 }; 37 38 } // namespace 39 40 class ResourceTrackerTest : public testing::Test { 41 public: 42 ResourceTrackerTest() {} 43 44 // Test implementation. 45 virtual void SetUp() OVERRIDE { 46 ASSERT_EQ(0, mock_resource_alive_count); 47 last_plugin_ref_was_deleted_count = 0; 48 instance_was_deleted_count = 0; 49 } 50 virtual void TearDown() OVERRIDE { 51 } 52 53 ResourceTracker& resource_tracker() { return *globals_.GetResourceTracker(); } 54 55 private: 56 TestGlobals globals_; 57 }; 58 59 // Test that LastPluginRefWasDeleted is called when the last plugin ref was 60 // deleted but the object lives on. 61 TEST_F(ResourceTrackerTest, LastPluginRef) { 62 PP_Instance instance = 0x1234567; 63 ProxyAutoLock lock; 64 resource_tracker().DidCreateInstance(instance); 65 66 scoped_refptr<MyMockResource> resource(new MyMockResource(instance)); 67 PP_Resource pp_resource = resource->GetReference(); 68 EXPECT_TRUE(resource_tracker().GetResource(pp_resource)); 69 70 // Releasing it should keep the object (because we have a ref) but fire the 71 // "last plugin ref" message. 72 resource_tracker().ReleaseResource(pp_resource); 73 EXPECT_EQ(1, last_plugin_ref_was_deleted_count); 74 EXPECT_EQ(1, mock_resource_alive_count); 75 76 resource_tracker().DidDeleteInstance(instance); 77 resource = NULL; 78 EXPECT_FALSE(resource_tracker().GetResource(pp_resource)); 79 } 80 81 // Tests when the plugin is holding a ref to a resource when the instance is 82 // deleted. 83 TEST_F(ResourceTrackerTest, InstanceDeletedWithPluginRef) { 84 // Make a resource with one ref held by the plugin, and delete the instance. 85 PP_Instance instance = 0x2345678; 86 ProxyAutoLock lock; 87 resource_tracker().DidCreateInstance(instance); 88 MyMockResource* resource = new MyMockResource(instance); 89 resource->GetReference(); 90 EXPECT_EQ(1, mock_resource_alive_count); 91 resource_tracker().DidDeleteInstance(instance); 92 93 // The resource should have been deleted, and before it was, it should have 94 // received a "last plugin ref was deleted" notification. 95 EXPECT_EQ(0, mock_resource_alive_count); 96 EXPECT_EQ(1, last_plugin_ref_was_deleted_count); 97 EXPECT_EQ(0, instance_was_deleted_count); 98 } 99 100 // Test when the plugin and the internal implementation (via scoped_refptr) is 101 // holding a ref to a resource when the instance is deleted. 102 TEST_F(ResourceTrackerTest, InstanceDeletedWithBothRefed) { 103 // Create a new instance. 104 PP_Instance instance = 0x3456789; 105 ProxyAutoLock lock; 106 107 // Make a resource with one ref held by the plugin and one ref held by us 108 // (outlives the plugin), and delete the instance. 109 resource_tracker().DidCreateInstance(instance); 110 scoped_refptr<MyMockResource> resource = new MyMockResource(instance); 111 resource->GetReference(); 112 EXPECT_EQ(1, mock_resource_alive_count); 113 resource_tracker().DidDeleteInstance(instance); 114 115 // The resource should NOT have been deleted, and it should have received both 116 // a "last plugin ref was deleted" and a "instance was deleted" notification. 117 EXPECT_EQ(1, mock_resource_alive_count); 118 EXPECT_EQ(1, last_plugin_ref_was_deleted_count); 119 EXPECT_EQ(1, instance_was_deleted_count); 120 EXPECT_EQ(0, resource->pp_instance()); 121 122 resource = NULL; 123 EXPECT_EQ(0, mock_resource_alive_count); 124 } 125 126 } // namespace ppapi 127