host_var_tracker_unittest.cc revision 58e6fbe4ee35d65e14b626c557d37565bf8ad179
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 "content/renderer/pepper/ppapi_unittest.h" 6 7#include "base/memory/scoped_ptr.h" 8#include "content/renderer/pepper/host_globals.h" 9#include "content/renderer/pepper/host_var_tracker.h" 10#include "content/renderer/pepper/mock_plugin_delegate.h" 11#include "content/renderer/pepper/mock_resource.h" 12#include "content/renderer/pepper/npapi_glue.h" 13#include "content/renderer/pepper/npobject_var.h" 14#include "content/renderer/pepper/pepper_plugin_instance_impl.h" 15#include "ppapi/c/pp_var.h" 16#include "ppapi/c/ppp_instance.h" 17#include "third_party/npapi/bindings/npruntime.h" 18#include "third_party/WebKit/public/web/WebBindings.h" 19 20using ppapi::NPObjectVar; 21 22namespace content { 23 24namespace { 25 26// Tracked NPObjects ----------------------------------------------------------- 27 28int g_npobjects_alive = 0; 29 30void TrackedClassDeallocate(NPObject* npobject) { 31 g_npobjects_alive--; 32 delete npobject; 33} 34 35NPClass g_tracked_npclass = { 36 NP_CLASS_STRUCT_VERSION, 37 NULL, 38 &TrackedClassDeallocate, 39 NULL, 40 NULL, 41 NULL, 42 NULL, 43 NULL, 44 NULL, 45 NULL, 46 NULL, 47 NULL, 48}; 49 50// Returns a new tracked NPObject with a refcount of 1. You'll want to put this 51// in a NPObjectReleaser to free this ref when the test completes. 52NPObject* NewTrackedNPObject() { 53 NPObject* object = new NPObject; 54 object->_class = &g_tracked_npclass; 55 object->referenceCount = 1; 56 57 g_npobjects_alive++; 58 return object; 59} 60 61class ReleaseNPObject { 62 public: 63 void operator()(NPObject* o) const { 64 WebKit::WebBindings::releaseObject(o); 65 } 66}; 67 68// Handles automatically releasing a reference to the NPObject on destruction. 69// It's assumed the input has a ref already taken. 70typedef scoped_ptr_malloc<NPObject, ReleaseNPObject> NPObjectReleaser; 71 72} // namespace 73 74class HostVarTrackerTest : public PpapiUnittest { 75 public: 76 HostVarTrackerTest() { 77 } 78 79 HostVarTracker& tracker() { 80 return *HostGlobals::Get()->host_var_tracker(); 81 } 82}; 83 84TEST_F(HostVarTrackerTest, DeleteObjectVarWithInstance) { 85 // Make a second instance (the test harness already creates & manages one). 86 scoped_refptr<PepperPluginInstanceImpl> instance2( 87 PepperPluginInstanceImpl::Create( 88 delegate(), NULL, module(), NULL, GURL())); 89 PP_Instance pp_instance2 = instance2->pp_instance(); 90 91 // Make an object var. 92 NPObjectReleaser npobject(NewTrackedNPObject()); 93 NPObjectToPPVarForTest(instance2.get(), npobject.get()); 94 95 EXPECT_EQ(1, g_npobjects_alive); 96 EXPECT_EQ(1, tracker().GetLiveNPObjectVarsForInstance(pp_instance2)); 97 98 // Free the instance, this should release the ObjectVar. 99 instance2 = NULL; 100 EXPECT_EQ(0, tracker().GetLiveNPObjectVarsForInstance(pp_instance2)); 101} 102 103// Make sure that using the same NPObject should give the same PP_Var 104// each time. 105TEST_F(HostVarTrackerTest, ReuseVar) { 106 NPObjectReleaser npobject(NewTrackedNPObject()); 107 108 PP_Var pp_object1 = NPObjectToPPVarForTest(instance(), npobject.get()); 109 PP_Var pp_object2 = NPObjectToPPVarForTest(instance(), npobject.get()); 110 111 // The two results should be the same. 112 EXPECT_EQ(pp_object1.value.as_id, pp_object2.value.as_id); 113 114 // The objects should be able to get us back to the associated NPObject. 115 // This ObjectVar must be released before we do NPObjectToPPVarForTest again 116 // below so it gets freed and we get a new identifier. 117 { 118 scoped_refptr<NPObjectVar> check_object(NPObjectVar::FromPPVar(pp_object1)); 119 ASSERT_TRUE(check_object.get()); 120 EXPECT_EQ(instance()->pp_instance(), check_object->pp_instance()); 121 EXPECT_EQ(npobject.get(), check_object->np_object()); 122 } 123 124 // Remove both of the refs we made above. 125 ::ppapi::VarTracker* var_tracker = 126 ::ppapi::PpapiGlobals::Get()->GetVarTracker(); 127 var_tracker->ReleaseVar(static_cast<int32_t>(pp_object2.value.as_id)); 128 var_tracker->ReleaseVar(static_cast<int32_t>(pp_object1.value.as_id)); 129 130 // Releasing the resource should free the internal ref, and so making a new 131 // one now should generate a new ID. 132 PP_Var pp_object3 = NPObjectToPPVarForTest(instance(), npobject.get()); 133 EXPECT_NE(pp_object1.value.as_id, pp_object3.value.as_id); 134 var_tracker->ReleaseVar(static_cast<int32_t>(pp_object3.value.as_id)); 135} 136 137} // namespace content 138