15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define UNIT_TEST // To get the ShadowingAtExitManager. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/at_exit.h" 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/test/plugin/plugin_thread_async_call_test.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 119ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string_util.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h" 14ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/test/plugin/plugin_client.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace NPAPIClient { 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// There are two plugin instances in this test. The long lived instance is used 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for reporting errors and signalling test completion. The short lived one is 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// used to verify that async callbacks are not invoked after NPP_Destroy. 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PluginThreadAsyncCallTest* g_short_lived_instance; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PluginThreadAsyncCallTest* g_long_lived_instance; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OnCallSucceededHelper(void* data) { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<PluginThreadAsyncCallTest*>(data)->OnCallSucceeded(); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OnCallFailed(void* data) { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_long_lived_instance->SetError("Async callback invoked after NPP_Destroy"); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OnCallCompletedHelper(void* data) { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<PluginThreadAsyncCallTest*>(data)->OnCallCompleted(); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PluginThreadAsyncCallTest::PluginThreadAsyncCallTest( 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPP id, NPNetscapeFuncs *host_functions) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : PluginTest(id, host_functions), at_exit_manager_(NULL) { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PluginThreadAsyncCallTest::~PluginThreadAsyncCallTest() { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete at_exit_manager_; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NPError PluginThreadAsyncCallTest::New( 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16 mode, int16 argc, const char* argn[], const char* argv[], 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPSavedData* saved) { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPError error = PluginTest::New(mode, argc, argn, argv, saved); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error != NPERR_NO_ERROR) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return error; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Determine whether this is the short lived instance. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < argc; ++i) { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::strcasecmp(argn[i], "short_lived") == 0) { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::strcasecmp(argv[i], "true") == 0) { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_short_lived_instance = this; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_long_lived_instance = this; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Schedule an async call that will succeed. Make sure to call that API from 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a different thread to fully test it. 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this == g_short_lived_instance) { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is slightly complicated thanks to the Linux shared library build, 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which shares more compilation units between the NPAPI plug-in and 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the base code. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) at_exit_manager_ = new base::ShadowingAtExitManager(); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread random_thread("random_thread"); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) random_thread.Start(); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) random_thread.message_loop()->PostTask( 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, base::Bind(&PluginThreadAsyncCallTest::AsyncCall, 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NPERR_NO_ERROR; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginThreadAsyncCallTest::AsyncCall() { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostFunctions()->pluginthreadasynccall(id(), OnCallSucceededHelper, this); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginThreadAsyncCallTest::OnCallSucceeded() { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delete the short lived instance. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPIdentifier delete_id = HostFunctions()->getstringidentifier( 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "deleteShortLivedInstance"); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPObject *window_obj = NULL; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostFunctions()->getvalue(id(), NPNVWindowNPObject, &window_obj); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPVariant result; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostFunctions()->invoke(id(), window_obj, delete_id, NULL, 0, &result); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NPError PluginThreadAsyncCallTest::Destroy() { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this == g_short_lived_instance) { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Schedule an async call that should not be called. 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostFunctions()->pluginthreadasynccall(id(), OnCallFailed, NULL); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Schedule an async call to end the test using the long lived instance. 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostFunctions()->pluginthreadasynccall(g_long_lived_instance->id(), 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnCallCompletedHelper, 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_long_lived_instance); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NPERR_NO_ERROR; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginThreadAsyncCallTest::OnCallCompleted() { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SignalTestCompleted(); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace NPAPIClient 118