Refactor management of overview window copy lifetime into a separate class.
[chromium-blink-merge.git] / content / test / plugin / plugin_delete_plugin_in_deallocate_test.cc
blob733107d2dc3added16613bf41d80af9683b23ad0
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.
5 #include "content/test/plugin/plugin_delete_plugin_in_deallocate_test.h"
7 #include "base/basictypes.h"
8 #include "base/compiler_specific.h"
10 namespace {
12 NPAPIClient::DeletePluginInDeallocateTest* g_signalling_instance_ = NULL;
14 class DeletePluginInDeallocateTestNPObject : public NPObject {
15 public:
16 DeletePluginInDeallocateTestNPObject()
17 : NPObject(), id_(NULL), host_functions_(NULL), deallocate_count_(0) {}
19 static NPObject* Allocate(NPP npp, NPClass* npclass) {
20 return new DeletePluginInDeallocateTestNPObject();
23 static void Deallocate(NPObject* npobject) {
24 DeletePluginInDeallocateTestNPObject* object =
25 reinterpret_cast<DeletePluginInDeallocateTestNPObject*>(npobject);
26 ++object->deallocate_count_;
28 // Call window.deletePlugin to tear-down our plugin from inside deallocate.
29 if (object->deallocate_count_ == 1) {
30 NPIdentifier delete_id =
31 object->host_functions_->getstringidentifier("deletePlugin");
32 NPObject* window_obj = NULL;
33 object->host_functions_->getvalue(object->id_, NPNVWindowNPObject,
34 &window_obj);
35 NPVariant rv;
36 object->host_functions_->invoke(object->id_, window_obj, delete_id, NULL,
37 0, &rv);
41 NPP id_;
42 NPNetscapeFuncs* host_functions_;
43 int deallocate_count_;
46 NPClass* GetDeletePluginInDeallocateTestClass() {
47 static NPClass plugin_class = {
48 NP_CLASS_STRUCT_VERSION,
49 DeletePluginInDeallocateTestNPObject::Allocate,
50 DeletePluginInDeallocateTestNPObject::Deallocate,
51 NULL, // Invalidate
52 NULL, // HasMethod
53 NULL, // Invoke
54 NULL, // InvokeDefault
55 NULL, // HasProperty
56 NULL, // GetProperty
57 NULL, // SetProperty
58 NULL, // RemoveProperty
60 return &plugin_class;
63 } // namespace
65 namespace NPAPIClient {
67 DeletePluginInDeallocateTest::DeletePluginInDeallocateTest(
68 NPP id, NPNetscapeFuncs* host_functions)
69 : PluginTest(id, host_functions), npobject_(NULL), test_started_(false) {
72 NPError DeletePluginInDeallocateTest::SetWindow(NPWindow* pNPWindow) {
73 #if !defined(OS_MACOSX)
74 if (pNPWindow->window == NULL)
75 return NPERR_NO_ERROR;
76 #endif
78 // Ensure that we run the test once, even if SetWindow is called again.
79 if (test_started_)
80 return NPERR_NO_ERROR;
81 test_started_ = true;
83 // Because of http://crbug.com/94829, we have to have a second plugin
84 // instance that we can use to signal completion.
85 if (test_id() == "signaller") {
86 g_signalling_instance_ = this;
87 return NPERR_NO_ERROR;
90 // Create a custom NPObject and give our Id and the Netscape function table.
91 npobject_ = HostFunctions()->createobject(
92 id(), GetDeletePluginInDeallocateTestClass());
93 DeletePluginInDeallocateTestNPObject* test_object =
94 reinterpret_cast<DeletePluginInDeallocateTestNPObject*>(npobject_);
95 test_object->id_ = id();
96 test_object->host_functions_ = HostFunctions();
98 // Fetch the window script object for our page.
99 NPObject* window = NULL;
100 HostFunctions()->getvalue(id(), NPNVWindowNPObject, &window);
102 // Pass it to the window.setTestObject function, which will later release it.
103 NPIdentifier set_test_object_id =
104 HostFunctions()->getstringidentifier("setTestObject");
105 NPVariant func_var;
106 NULL_TO_NPVARIANT(func_var);
107 HostFunctions()->getproperty(id(), window, set_test_object_id, &func_var);
109 NPObject* func = NPVARIANT_TO_OBJECT(func_var);
110 NPVariant func_arg;
111 OBJECT_TO_NPVARIANT(npobject_, func_arg);
112 NPVariant func_result;
113 HostFunctions()->invokeDefault(id(), func, &func_arg, 1,
114 &func_result);
116 // Release the object - the page's reference should keep it alive.
117 HostFunctions()->releaseobject(npobject_);
119 return NPERR_NO_ERROR;
122 NPError DeletePluginInDeallocateTest::Destroy() {
123 // Because of http://crbug.com/94829, we can't signal completion from within
124 // the NPP_Destroy of the plugin that is being destroyed. We work-around
125 // that by testing using a second instance, and signalling though the main
126 // test instance.
128 // There should always be a signalling instance by the time we reach here.
129 if (!g_signalling_instance_)
130 return NPERR_NO_ERROR;
132 // If we're the signalling instance, do nothing.
133 if (g_signalling_instance_ == this)
134 return NPERR_NO_ERROR;
136 if (!npobject_) {
137 g_signalling_instance_->SetError("SetWindow was not invoked.");
138 } else {
139 // Verify that our object was deallocated exactly once.
140 DeletePluginInDeallocateTestNPObject* test_object =
141 reinterpret_cast<DeletePluginInDeallocateTestNPObject*>(npobject_);
142 if (test_object->deallocate_count_ != 1)
143 g_signalling_instance_->SetError(
144 "Object was not deallocated exactly once.");
145 delete test_object;
148 g_signalling_instance_->SignalTestCompleted();
150 return NPERR_NO_ERROR;
153 } // namespace NPAPIClient