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