Roll src/third_party/WebKit e0eac24:489c548 (svn 193311:193320)
[chromium-blink-merge.git] / content / test / plugin / plugin_thread_async_call_test.cc
blob4afd00425f061b1fe7a3e9ad32a631dfcd79326d
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 #define UNIT_TEST // To get the ShadowingAtExitManager.
6 #include "base/at_exit.h"
8 #include "content/test/plugin/plugin_thread_async_call_test.h"
10 #include "base/bind.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/strings/string_util.h"
13 #include "base/threading/thread.h"
14 #include "content/test/plugin/plugin_client.h"
16 namespace NPAPIClient {
18 namespace {
20 // There are two plugin instances in this test. The long lived instance is used
21 // for reporting errors and signalling test completion. The short lived one is
22 // used to verify that async callbacks are not invoked after NPP_Destroy.
23 PluginThreadAsyncCallTest* g_short_lived_instance;
24 PluginThreadAsyncCallTest* g_long_lived_instance;
26 void OnCallSucceededHelper(void* data) {
27 static_cast<PluginThreadAsyncCallTest*>(data)->OnCallSucceeded();
30 void OnCallFailed(void* data) {
31 g_long_lived_instance->SetError("Async callback invoked after NPP_Destroy");
34 void OnCallCompletedHelper(void* data) {
35 static_cast<PluginThreadAsyncCallTest*>(data)->OnCallCompleted();
39 PluginThreadAsyncCallTest::PluginThreadAsyncCallTest(
40 NPP id, NPNetscapeFuncs *host_functions)
41 : PluginTest(id, host_functions), at_exit_manager_(NULL) {
44 PluginThreadAsyncCallTest::~PluginThreadAsyncCallTest() {
45 delete at_exit_manager_;
48 NPError PluginThreadAsyncCallTest::New(
49 uint16 mode, int16 argc, const char* argn[], const char* argv[],
50 NPSavedData* saved) {
51 NPError error = PluginTest::New(mode, argc, argn, argv, saved);
52 if (error != NPERR_NO_ERROR)
53 return error;
55 // Determine whether this is the short lived instance.
56 for (int i = 0; i < argc; ++i) {
57 if (base::strcasecmp(argn[i], "short_lived") == 0) {
58 if (base::strcasecmp(argv[i], "true") == 0) {
59 g_short_lived_instance = this;
60 } else {
61 g_long_lived_instance = this;
66 // Schedule an async call that will succeed. Make sure to call that API from
67 // a different thread to fully test it.
68 if (this == g_short_lived_instance) {
69 // This is slightly complicated thanks to the Linux shared library build,
70 // which shares more compilation units between the NPAPI plugin and
71 // the base code.
72 at_exit_manager_ = new base::ShadowingAtExitManager();
73 base::Thread random_thread("random_thread");
74 random_thread.Start();
75 random_thread.message_loop()->PostTask(
76 FROM_HERE, base::Bind(&PluginThreadAsyncCallTest::AsyncCall,
77 base::Unretained(this)));
80 return NPERR_NO_ERROR;
83 void PluginThreadAsyncCallTest::AsyncCall() {
84 HostFunctions()->pluginthreadasynccall(id(), OnCallSucceededHelper, this);
87 void PluginThreadAsyncCallTest::OnCallSucceeded() {
88 // Delete the short lived instance.
89 NPIdentifier delete_id = HostFunctions()->getstringidentifier(
90 "deleteShortLivedInstance");
92 NPObject *window_obj = NULL;
93 HostFunctions()->getvalue(id(), NPNVWindowNPObject, &window_obj);
95 NPVariant result;
96 HostFunctions()->invoke(id(), window_obj, delete_id, NULL, 0, &result);
99 NPError PluginThreadAsyncCallTest::Destroy() {
100 if (this == g_short_lived_instance) {
101 // Schedule an async call that should not be called.
102 HostFunctions()->pluginthreadasynccall(id(), OnCallFailed, NULL);
104 // Schedule an async call to end the test using the long lived instance.
105 HostFunctions()->pluginthreadasynccall(g_long_lived_instance->id(),
106 OnCallCompletedHelper,
107 g_long_lived_instance);
110 return NPERR_NO_ERROR;
113 void PluginThreadAsyncCallTest::OnCallCompleted() {
114 SignalTestCompleted();
117 } // namespace NPAPIClient