Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(248)

Side by Side Diff: ppapi/tests/test_message_handler.cc

Issue 318763003: PPAPI: Add C++ wrapper for MessageHandler stuff. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: move messag_handler.h to HEADERS section of library.dsc Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ppapi/ppapi_sources.gypi ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ppapi/tests/test_message_handler.h" 5 #include "ppapi/tests/test_message_handler.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 #include <algorithm> 8 #include <algorithm>
9 #include <map> 9 #include <map>
10 #include <sstream> 10 #include <sstream>
11 11
12 #include "ppapi/c/pp_var.h" 12 #include "ppapi/c/pp_var.h"
13 #include "ppapi/c/ppb_file_io.h" 13 #include "ppapi/c/ppb_file_io.h"
14 #include "ppapi/c/ppb_messaging.h" 14 #include "ppapi/c/ppb_messaging.h"
15 #include "ppapi/c/ppp_message_handler.h" 15 #include "ppapi/c/ppp_message_handler.h"
16 #include "ppapi/cpp/file_io.h" 16 #include "ppapi/cpp/file_io.h"
17 #include "ppapi/cpp/file_ref.h" 17 #include "ppapi/cpp/file_ref.h"
18 #include "ppapi/cpp/file_system.h" 18 #include "ppapi/cpp/file_system.h"
19 #include "ppapi/cpp/instance.h" 19 #include "ppapi/cpp/instance.h"
20 #include "ppapi/cpp/message_handler.h"
20 #include "ppapi/cpp/module_impl.h" 21 #include "ppapi/cpp/module_impl.h"
21 #include "ppapi/cpp/var.h" 22 #include "ppapi/cpp/var.h"
22 #include "ppapi/cpp/var_array.h" 23 #include "ppapi/cpp/var_array.h"
23 #include "ppapi/cpp/var_array_buffer.h" 24 #include "ppapi/cpp/var_array_buffer.h"
24 #include "ppapi/cpp/var_dictionary.h" 25 #include "ppapi/cpp/var_dictionary.h"
25 #include "ppapi/tests/pp_thread.h" 26 #include "ppapi/tests/pp_thread.h"
26 #include "ppapi/tests/test_utils.h" 27 #include "ppapi/tests/test_utils.h"
27 #include "ppapi/tests/testing_instance.h" 28 #include "ppapi/tests/testing_instance.h"
28 29
29 // Windows defines 'PostMessage', so we have to undef it. 30 // Windows defines 'PostMessage', so we have to undef it.
30 #ifdef PostMessage 31 #ifdef PostMessage
31 #undef PostMessage 32 #undef PostMessage
32 #endif 33 #endif
33 34
34 REGISTER_TEST_CASE(MessageHandler); 35 REGISTER_TEST_CASE(MessageHandler);
35 36
36 namespace { 37 namespace {
37 38
38 // Created and destroyed on the main thread. All public methods should be called 39 // Created and destroyed on the main thread. All public methods should be called
39 // on the main thread. Most data members are only accessed on the main thread. 40 // on the main thread. Most data members are only accessed on the main thread.
40 // (Though it handles messages on the background thread). 41 // (Though it handles messages on the background thread).
41 class EchoingMessageHandler { 42 class EchoingMessageHandler : public pp::MessageHandler {
42 public: 43 public:
43 explicit EchoingMessageHandler(PP_Instance instance, 44 explicit EchoingMessageHandler(TestingInstance* instance,
44 const pp::MessageLoop& loop) 45 const pp::MessageLoop& loop)
45 : pp_instance_(instance), 46 : testing_instance_(instance),
46 message_handler_loop_(loop), 47 message_handler_loop_(loop),
47 ppb_messaging_if_(static_cast<const PPB_Messaging_1_2*>(
48 pp::Module::Get()->GetBrowserInterface(
49 PPB_MESSAGING_INTERFACE_1_2))),
50 ppp_message_handler_if_(),
51 is_registered_(false), 48 is_registered_(false),
52 test_finished_event_(instance), 49 test_finished_event_(instance->pp_instance()),
53 destroy_event_(instance) { 50 destroy_event_(instance->pp_instance()) {
54 AssertOnMainThread(); 51 AssertOnMainThread();
55 ppp_message_handler_if_.HandleMessage = &HandleMessage;
56 ppp_message_handler_if_.HandleBlockingMessage = &HandleBlockingMessage;
57 ppp_message_handler_if_.Destroy = &Destroy;
58 } 52 }
59 void Register() { 53 void Register() {
60 AssertOnMainThread(); 54 AssertOnMainThread();
61 assert(!is_registered_); 55 assert(!is_registered_);
62 int32_t result = ppb_messaging_if_->RegisterMessageHandler( 56 int32_t result =
63 pp_instance_, 57 testing_instance_->RegisterMessageHandler(this, message_handler_loop_);
64 this,
65 &ppp_message_handler_if_,
66 message_handler_loop_.pp_resource());
67 if (result == PP_OK) { 58 if (result == PP_OK) {
68 is_registered_ = true; 59 is_registered_ = true;
69 } else { 60 } else {
70 std::ostringstream stream; 61 std::ostringstream stream;
71 stream << "Failed to register message handler; got error " << result; 62 stream << "Failed to register message handler; got error " << result;
72 AddError(stream.str()); 63 AddError(stream.str());
73 test_finished_event_.Signal(); 64 test_finished_event_.Signal();
74 } 65 }
75 // Note, at this point, we can't safely read or write errors_ until we wait 66 // Note, at this point, we can't safely read or write errors_ until we wait
76 // on destroy_event_. 67 // on destroy_event_.
77 } 68 }
78 void Unregister() { 69 void Unregister() {
79 AssertOnMainThread(); 70 AssertOnMainThread();
80 assert(is_registered_); 71 assert(is_registered_);
81 ppb_messaging_if_->UnregisterMessageHandler(pp_instance_); 72 testing_instance_->UnregisterMessageHandler();
82 is_registered_ = false; 73 is_registered_ = false;
83 } 74 }
84 void WaitForTestFinishedMessage() { 75 void WaitForTestFinishedMessage() {
85 test_finished_event_.Wait(); 76 test_finished_event_.Wait();
86 test_finished_event_.Reset(); 77 test_finished_event_.Reset();
87 } 78 }
88 // Wait for Destroy() to be called on the MessageHandler thread. When it's 79 // Wait for Destroy() to be called on the MessageHandler thread. When it's
89 // done, return any errors that occurred during the time the MessageHandler 80 // done, return any errors that occurred during the time the MessageHandler
90 // was getting messages. 81 // was getting messages.
91 std::string WaitForDestroy() { 82 std::string WaitForDestroy() {
(...skipping 14 matching lines...) Expand all
106 assert(pp::MessageLoop::GetForMainThread() == 97 assert(pp::MessageLoop::GetForMainThread() ==
107 pp::MessageLoop::GetCurrent()); 98 pp::MessageLoop::GetCurrent());
108 } 99 }
109 void AddError(const std::string& error) { 100 void AddError(const std::string& error) {
110 if (!error.empty()) { 101 if (!error.empty()) {
111 if (!errors_.empty()) 102 if (!errors_.empty())
112 errors_ += "<p>"; 103 errors_ += "<p>";
113 errors_ += error; 104 errors_ += error;
114 } 105 }
115 } 106 }
116 static void HandleMessage(PP_Instance instance, 107 virtual void HandleMessage(pp::InstanceHandle instance, const pp::Var& var) {
117 void* user_data, 108 if (pp::MessageLoop::GetCurrent() != message_handler_loop_)
118 const PP_Var* message_data) { 109 AddError("HandleMessage was called on the wrong thread!");
119 EchoingMessageHandler* thiz = 110 if (instance.pp_instance() != testing_instance_->pp_instance())
120 static_cast<EchoingMessageHandler*>(user_data); 111 AddError("HandleMessage was passed the wrong instance!");
121 if (pp::MessageLoop::GetCurrent() != thiz->message_handler_loop_)
122 thiz->AddError("HandleMessage was called on the wrong thread!");
123 if (instance != thiz->pp_instance_)
124 thiz->AddError("HandleMessage was passed the wrong instance!");
125 pp::Var var(*message_data);
126 if (var.is_string() && var.AsString() == "FINISHED_TEST") 112 if (var.is_string() && var.AsString() == "FINISHED_TEST")
127 thiz->test_finished_event_.Signal(); 113 test_finished_event_.Signal();
128 else 114 else
129 thiz->ppb_messaging_if_->PostMessage(instance, *message_data); 115 testing_instance_->PostMessage(var);
130 } 116 }
131 117
132 static void HandleBlockingMessage(PP_Instance instance, 118 virtual pp::Var HandleBlockingMessage(pp::InstanceHandle instance,
133 void* user_data, 119 const pp::Var& var) {
134 const PP_Var* message_data, 120 if (pp::MessageLoop::GetCurrent() != message_handler_loop_)
135 PP_Var* result) { 121 AddError("HandleBlockingMessage was called on the wrong thread!");
136 EchoingMessageHandler* thiz = 122 if (instance.pp_instance() != testing_instance_->pp_instance())
137 static_cast<EchoingMessageHandler*>(user_data); 123 AddError("HandleBlockingMessage was passed the wrong instance!");
138 if (pp::MessageLoop::GetCurrent() != thiz->message_handler_loop_)
139 thiz->AddError("HandleBlockingMessage was called on the wrong thread!");
140 if (instance != thiz->pp_instance_)
141 thiz->AddError("HandleBlockingMessage was passed the wrong instance!");
142 124
143 // The PP_Var we are passed is an in-parameter, so the browser is not 125 return var;
144 // giving us a ref-count. The ref-count it has will be decremented after we
145 // return. But we need to add a ref when returning a PP_Var, to pass to the
146 // caller.
147 pp::Var take_ref(*message_data);
148 take_ref.Detach();
149 *result = *message_data;
150 } 126 }
151 127
152 static void Destroy(PP_Instance instance, void* user_data) { 128 virtual void WasUnregistered(pp::InstanceHandle instance) {
153 EchoingMessageHandler* thiz = 129 if (pp::MessageLoop::GetCurrent() != message_handler_loop_)
154 static_cast<EchoingMessageHandler*>(user_data); 130 AddError("Destroy was called on the wrong thread!");
155 if (pp::MessageLoop::GetCurrent() != thiz->message_handler_loop_) 131 if (instance.pp_instance() != testing_instance_->pp_instance())
156 thiz->AddError("Destroy was called on the wrong thread!"); 132 AddError("Destroy was passed the wrong instance!");
157 if (instance != thiz->pp_instance_) 133 destroy_event_.Signal();
158 thiz->AddError("Destroy was passed the wrong instance!");
159 thiz->destroy_event_.Signal();
160 } 134 }
161 135
162 // These data members are initialized on the main thread, but don't change for 136 // These data members are initialized on the main thread, but don't change for
163 // the life of the object, so are safe to access on the background thread, 137 // the life of the object, so are safe to access on the background thread,
164 // because there will be a memory barrier before the the MessageHandler calls 138 // because there will be a memory barrier before the the MessageHandler calls
165 // are invoked. 139 // are invoked.
166 const PP_Instance pp_instance_; 140 TestingInstance* const testing_instance_;
167 const pp::MessageLoop message_handler_loop_; 141 const pp::MessageLoop message_handler_loop_;
168 const pp::MessageLoop main_loop_; 142 const pp::MessageLoop main_loop_;
169 const PPB_Messaging_1_2* const ppb_messaging_if_;
170 // Spiritually, this member is const, but we can't initialize it in C++03,
171 // so it has to be non-const to be set in the constructor body.
172 PPP_MessageHandler_0_2 ppp_message_handler_if_;
173 143
174 // is_registered_ is only read/written on the main thread. 144 // is_registered_ is only read/written on the main thread.
175 bool is_registered_; 145 bool is_registered_;
176 146
177 // errors_ is written on the MessageHandler thread. When Destroy() is 147 // errors_ is written on the MessageHandler thread. When Destroy() is
178 // called, we stop writing to errors_ and signal destroy_event_. This causes 148 // called, we stop writing to errors_ and signal destroy_event_. This causes
179 // a memory barrier, so it's safe to read errors_ after that. 149 // a memory barrier, so it's safe to read errors_ after that.
180 std::string errors_; 150 std::string errors_;
181 NestedEvent test_finished_event_; 151 NestedEvent test_finished_event_;
182 NestedEvent destroy_event_; 152 NestedEvent destroy_event_;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 reinterpret_cast<void*>(0xdeadbeef), 221 reinterpret_cast<void*>(0xdeadbeef),
252 &bad_ppp_ifs[i], 222 &bad_ppp_ifs[i],
253 handler_thread_.message_loop().pp_resource()); 223 handler_thread_.message_loop().pp_resource());
254 ASSERT_EQ(PP_ERROR_BADARGUMENT, result); 224 ASSERT_EQ(PP_ERROR_BADARGUMENT, result);
255 } 225 }
256 } 226 }
257 PASS(); 227 PASS();
258 } 228 }
259 229
260 std::string TestMessageHandler::TestPostMessageAndAwaitResponse() { 230 std::string TestMessageHandler::TestPostMessageAndAwaitResponse() {
261 EchoingMessageHandler handler(instance()->pp_instance(), 231 EchoingMessageHandler handler(instance(),
262 handler_thread_.message_loop()); 232 handler_thread_.message_loop());
263 handler.Register(); 233 handler.Register();
264 std::string js_code("var plugin = document.getElementById('plugin');\n"); 234 std::string js_code("var plugin = document.getElementById('plugin');\n");
265 js_code += "var result = undefined;\n"; 235 js_code += "var result = undefined;\n";
266 const char* const values_to_test[] = { 236 const char* const values_to_test[] = {
267 "5", 237 "5",
268 "undefined", 238 "undefined",
269 "1.5", 239 "1.5",
270 "'hello'", 240 "'hello'",
271 "{'key': 'value', 'array_key': [1, 2, 3, 4, 5]}", 241 "{'key': 'value', 'array_key': [1, 2, 3, 4, 5]}",
(...skipping 17 matching lines...) Expand all
289 // That should be fixed before this API goes to stable. See crbug.com/384528 259 // That should be fixed before this API goes to stable. See crbug.com/384528
290 js_code += "plugin.postMessage('FINISHED_TEST');\n"; 260 js_code += "plugin.postMessage('FINISHED_TEST');\n";
291 instance_->EvalScript(js_code); 261 instance_->EvalScript(js_code);
292 handler.WaitForTestFinishedMessage(); 262 handler.WaitForTestFinishedMessage();
293 handler.Unregister(); 263 handler.Unregister();
294 ASSERT_SUBTEST_SUCCESS(handler.WaitForDestroy()); 264 ASSERT_SUBTEST_SUCCESS(handler.WaitForDestroy());
295 265
296 PASS(); 266 PASS();
297 } 267 }
298 268
OLDNEW
« no previous file with comments | « ppapi/ppapi_sources.gypi ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698