| Index: webkit/plugins/npapi/test/plugin_delete_plugin_in_deallocate_test.cc
|
| diff --git a/webkit/plugins/npapi/test/plugin_delete_plugin_in_deallocate_test.cc b/webkit/plugins/npapi/test/plugin_delete_plugin_in_deallocate_test.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..d4c9b52e138eb0454053cbb5e1397b13fbe57fc7
|
| --- /dev/null
|
| +++ b/webkit/plugins/npapi/test/plugin_delete_plugin_in_deallocate_test.cc
|
| @@ -0,0 +1,120 @@
|
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "webkit/plugins/npapi/test/plugin_delete_plugin_in_deallocate_test.h"
|
| +
|
| +#include "base/basictypes.h"
|
| +#include "base/compiler_specific.h"
|
| +
|
| +namespace {
|
| +
|
| +class DeletePluginInDeallocateTestNPObject : public NPObject {
|
| + public:
|
| + DeletePluginInDeallocateTestNPObject()
|
| + : NPObject(), id_(NULL), host_functions_(NULL), deallocate_count_(0) {}
|
| +
|
| + static NPObject* Allocate(NPP npp, NPClass* npclass) {
|
| + return new DeletePluginInDeallocateTestNPObject();
|
| + }
|
| +
|
| + static void Deallocate(NPObject* npobject) {
|
| + DeletePluginInDeallocateTestNPObject* object =
|
| + reinterpret_cast<DeletePluginInDeallocateTestNPObject*>(npobject);
|
| + ++object->deallocate_count_;
|
| +
|
| + // Call window.deletePlugin to tear-down our plugin from inside deallocate.
|
| + if (object->deallocate_count_ == 1) {
|
| + NPIdentifier delete_id =
|
| + object->host_functions_->getstringidentifier("deletePlugin");
|
| + NPObject* window_obj = NULL;
|
| + object->host_functions_->getvalue(object->id_, NPNVWindowNPObject,
|
| + &window_obj);
|
| + NPVariant rv;
|
| + object->host_functions_->invoke(object->id_, window_obj, delete_id, NULL,
|
| + 0, &rv);
|
| + }
|
| + }
|
| +
|
| + NPP id_;
|
| + NPNetscapeFuncs* host_functions_;
|
| + int deallocate_count_;
|
| +};
|
| +
|
| +NPClass* GetDeletePluginInDeallocateTestClass() {
|
| + static NPClass plugin_class = {
|
| + NP_CLASS_STRUCT_VERSION,
|
| + DeletePluginInDeallocateTestNPObject::Allocate,
|
| + DeletePluginInDeallocateTestNPObject::Deallocate,
|
| + NULL, // Invalidate
|
| + NULL, // HasMethod
|
| + NULL, // Invoke
|
| + NULL, // InvokeDefault
|
| + NULL, // HasProperty
|
| + NULL, // GetProperty
|
| + NULL, // SetProperty
|
| + NULL, // RemoveProperty
|
| + };
|
| + return &plugin_class;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +namespace NPAPIClient {
|
| +
|
| +DeletePluginInDeallocateTest::DeletePluginInDeallocateTest(
|
| + NPP id, NPNetscapeFuncs *host_functions)
|
| + : PluginTest(id, host_functions), npobject_(NULL) {
|
| +}
|
| +
|
| +NPError DeletePluginInDeallocateTest::SetWindow(NPWindow* pNPWindow) {
|
| + if (pNPWindow->window == NULL)
|
| + return NPERR_NO_ERROR;
|
| +
|
| + NPObject* window = NULL;
|
| + HostFunctions()->getvalue(id(), NPNVWindowNPObject, &window);
|
| +
|
| + // Create a custom NPObject and give our Id and the Netscape function table.
|
| + npobject_ = HostFunctions()->createobject(
|
| + id(), GetDeletePluginInDeallocateTestClass());
|
| + DeletePluginInDeallocateTestNPObject* test_object =
|
| + reinterpret_cast<DeletePluginInDeallocateTestNPObject*>(npobject_);
|
| + test_object->id_ = id();
|
| + test_object->host_functions_ = HostFunctions();
|
| +
|
| + // Pass it to the window.setTestObject function, which will later release it.
|
| + NPIdentifier set_test_object_id =
|
| + HostFunctions()->getstringidentifier("setTestObject");
|
| + NPVariant func_var;
|
| + HostFunctions()->getproperty(id(), window, set_test_object_id, &func_var);
|
| + NPObject* func = NPVARIANT_TO_OBJECT(func_var);
|
| + NPVariant func_arg;
|
| + OBJECT_TO_NPVARIANT(npobject_, func_arg);
|
| + NPVariant func_result;
|
| + HostFunctions()->invokeDefault(id(), func, &func_arg, 1,
|
| + &func_result);
|
| +
|
| + // Release the object - the page's reference should keep it alive.
|
| + HostFunctions()->releaseobject(npobject_);
|
| +
|
| + return NPERR_NO_ERROR;
|
| +}
|
| +
|
| +NPError DeletePluginInDeallocateTest::Destroy() {
|
| + if (!npobject_) {
|
| + SetError("SetWindow was not invoked.");
|
| + } else {
|
| + // Verify that our object was deallocated exactly once.
|
| + DeletePluginInDeallocateTestNPObject* test_object =
|
| + reinterpret_cast<DeletePluginInDeallocateTestNPObject*>(npobject_);
|
| + if (test_object->deallocate_count_ != 1)
|
| + SetError("Object was not deallocated exactly once.");
|
| + delete test_object;
|
| + }
|
| +
|
| + SignalTestCompleted();
|
| +
|
| + return NPERR_NO_ERROR;
|
| +}
|
| +
|
| +} // namespace NPAPIClient
|
|
|