OLD | NEW |
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/ppp_message_handler.h" | 15 #include "ppapi/c/ppp_message_handler.h" |
15 #include "ppapi/cpp/file_io.h" | 16 #include "ppapi/cpp/file_io.h" |
16 #include "ppapi/cpp/file_ref.h" | 17 #include "ppapi/cpp/file_ref.h" |
17 #include "ppapi/cpp/file_system.h" | 18 #include "ppapi/cpp/file_system.h" |
18 #include "ppapi/cpp/instance.h" | 19 #include "ppapi/cpp/instance.h" |
19 #include "ppapi/cpp/module_impl.h" | 20 #include "ppapi/cpp/module_impl.h" |
20 #include "ppapi/cpp/var.h" | 21 #include "ppapi/cpp/var.h" |
21 #include "ppapi/cpp/var_array.h" | 22 #include "ppapi/cpp/var_array.h" |
22 #include "ppapi/cpp/var_array_buffer.h" | 23 #include "ppapi/cpp/var_array_buffer.h" |
23 #include "ppapi/cpp/var_dictionary.h" | 24 #include "ppapi/cpp/var_dictionary.h" |
(...skipping 12 matching lines...) Expand all Loading... |
36 | 37 |
37 // Created and destroyed on the main thread. All public methods should be called | 38 // Created and destroyed on the main thread. All public methods should be called |
38 // on the main thread. Most data members are only accessed on the main thread. | 39 // on the main thread. Most data members are only accessed on the main thread. |
39 // (Though it handles messages on the background thread). | 40 // (Though it handles messages on the background thread). |
40 class EchoingMessageHandler { | 41 class EchoingMessageHandler { |
41 public: | 42 public: |
42 explicit EchoingMessageHandler(PP_Instance instance, | 43 explicit EchoingMessageHandler(PP_Instance instance, |
43 const pp::MessageLoop& loop) | 44 const pp::MessageLoop& loop) |
44 : pp_instance_(instance), | 45 : pp_instance_(instance), |
45 message_handler_loop_(loop), | 46 message_handler_loop_(loop), |
46 ppb_messaging_if_(static_cast<const PPB_Messaging_1_1*>( | 47 ppb_messaging_if_(static_cast<const PPB_Messaging_1_2*>( |
47 pp::Module::Get()->GetBrowserInterface( | 48 pp::Module::Get()->GetBrowserInterface( |
48 PPB_MESSAGING_INTERFACE_1_1))), | 49 PPB_MESSAGING_INTERFACE_1_2))), |
49 ppp_message_handler_if_(), | 50 ppp_message_handler_if_(), |
50 is_registered_(false), | 51 is_registered_(false), |
51 test_finished_event_(instance), | 52 test_finished_event_(instance), |
52 destroy_event_(instance) { | 53 destroy_event_(instance) { |
53 AssertOnMainThread(); | 54 AssertOnMainThread(); |
54 ppp_message_handler_if_.HandleMessage = &HandleMessage; | 55 ppp_message_handler_if_.HandleMessage = &HandleMessage; |
55 ppp_message_handler_if_.HandleBlockingMessage = &HandleBlockingMessage; | 56 ppp_message_handler_if_.HandleBlockingMessage = &HandleBlockingMessage; |
56 ppp_message_handler_if_.Destroy = &Destroy; | 57 ppp_message_handler_if_.Destroy = &Destroy; |
57 } | 58 } |
58 void Register() { | 59 void Register() { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 } | 108 } |
108 void AddError(const std::string& error) { | 109 void AddError(const std::string& error) { |
109 if (!error.empty()) { | 110 if (!error.empty()) { |
110 if (!errors_.empty()) | 111 if (!errors_.empty()) |
111 errors_ += "<p>"; | 112 errors_ += "<p>"; |
112 errors_ += error; | 113 errors_ += error; |
113 } | 114 } |
114 } | 115 } |
115 static void HandleMessage(PP_Instance instance, | 116 static void HandleMessage(PP_Instance instance, |
116 void* user_data, | 117 void* user_data, |
117 struct PP_Var message_data) { | 118 const PP_Var* message_data) { |
118 EchoingMessageHandler* thiz = | 119 EchoingMessageHandler* thiz = |
119 static_cast<EchoingMessageHandler*>(user_data); | 120 static_cast<EchoingMessageHandler*>(user_data); |
120 if (pp::MessageLoop::GetCurrent() != thiz->message_handler_loop_) | 121 if (pp::MessageLoop::GetCurrent() != thiz->message_handler_loop_) |
121 thiz->AddError("HandleMessage was called on the wrong thread!"); | 122 thiz->AddError("HandleMessage was called on the wrong thread!"); |
122 if (instance != thiz->pp_instance_) | 123 if (instance != thiz->pp_instance_) |
123 thiz->AddError("HandleMessage was passed the wrong instance!"); | 124 thiz->AddError("HandleMessage was passed the wrong instance!"); |
124 pp::Var var(message_data); | 125 pp::Var var(*message_data); |
125 if (var.is_string() && var.AsString() == "FINISHED_TEST") | 126 if (var.is_string() && var.AsString() == "FINISHED_TEST") |
126 thiz->test_finished_event_.Signal(); | 127 thiz->test_finished_event_.Signal(); |
127 else | 128 else |
128 thiz->ppb_messaging_if_->PostMessage(instance, message_data); | 129 thiz->ppb_messaging_if_->PostMessage(instance, *message_data); |
129 } | 130 } |
130 | 131 |
131 static PP_Var HandleBlockingMessage(PP_Instance instance, | 132 static void HandleBlockingMessage(PP_Instance instance, |
132 void* user_data, | 133 void* user_data, |
133 struct PP_Var message_data) { | 134 const PP_Var* message_data, |
| 135 PP_Var* result) { |
134 EchoingMessageHandler* thiz = | 136 EchoingMessageHandler* thiz = |
135 static_cast<EchoingMessageHandler*>(user_data); | 137 static_cast<EchoingMessageHandler*>(user_data); |
136 if (pp::MessageLoop::GetCurrent() != thiz->message_handler_loop_) | 138 if (pp::MessageLoop::GetCurrent() != thiz->message_handler_loop_) |
137 thiz->AddError("HandleBlockingMessage was called on the wrong thread!"); | 139 thiz->AddError("HandleBlockingMessage was called on the wrong thread!"); |
138 if (instance != thiz->pp_instance_) | 140 if (instance != thiz->pp_instance_) |
139 thiz->AddError("HandleBlockingMessage was passed the wrong instance!"); | 141 thiz->AddError("HandleBlockingMessage was passed the wrong instance!"); |
140 | 142 |
141 // The PP_Var we are passed is an in-parameter, so the browser is not | 143 // The PP_Var we are passed is an in-parameter, so the browser is not |
142 // giving us a ref-count. The ref-count it has will be decremented after we | 144 // giving us a ref-count. The ref-count it has will be decremented after we |
143 // return. But we need to add a ref when returning a PP_Var, to pass to the | 145 // return. But we need to add a ref when returning a PP_Var, to pass to the |
144 // caller. | 146 // caller. |
145 pp::Var take_ref(message_data); | 147 pp::Var take_ref(*message_data); |
146 take_ref.Detach(); | 148 take_ref.Detach(); |
147 return message_data; | 149 *result = *message_data; |
148 } | 150 } |
149 | 151 |
150 static void Destroy(PP_Instance instance, void* user_data) { | 152 static void Destroy(PP_Instance instance, void* user_data) { |
151 EchoingMessageHandler* thiz = | 153 EchoingMessageHandler* thiz = |
152 static_cast<EchoingMessageHandler*>(user_data); | 154 static_cast<EchoingMessageHandler*>(user_data); |
153 if (pp::MessageLoop::GetCurrent() != thiz->message_handler_loop_) | 155 if (pp::MessageLoop::GetCurrent() != thiz->message_handler_loop_) |
154 thiz->AddError("Destroy was called on the wrong thread!"); | 156 thiz->AddError("Destroy was called on the wrong thread!"); |
155 if (instance != thiz->pp_instance_) | 157 if (instance != thiz->pp_instance_) |
156 thiz->AddError("Destroy was passed the wrong instance!"); | 158 thiz->AddError("Destroy was passed the wrong instance!"); |
157 thiz->destroy_event_.Signal(); | 159 thiz->destroy_event_.Signal(); |
158 } | 160 } |
159 | 161 |
160 // These data members are initialized on the main thread, but don't change for | 162 // These data members are initialized on the main thread, but don't change for |
161 // the life of the object, so are safe to access on the background thread, | 163 // the life of the object, so are safe to access on the background thread, |
162 // because there will be a memory barrier before the the MessageHandler calls | 164 // because there will be a memory barrier before the the MessageHandler calls |
163 // are invoked. | 165 // are invoked. |
164 const PP_Instance pp_instance_; | 166 const PP_Instance pp_instance_; |
165 const pp::MessageLoop message_handler_loop_; | 167 const pp::MessageLoop message_handler_loop_; |
166 const pp::MessageLoop main_loop_; | 168 const pp::MessageLoop main_loop_; |
167 const PPB_Messaging_1_1* const ppb_messaging_if_; | 169 const PPB_Messaging_1_2* const ppb_messaging_if_; |
168 // Spiritually, this member is const, but we can't initialize it in C++03, | 170 // Spiritually, this member is const, but we can't initialize it in C++03, |
169 // so it has to be non-const to be set in the constructor body. | 171 // so it has to be non-const to be set in the constructor body. |
170 PPP_MessageHandler_0_1 ppp_message_handler_if_; | 172 PPP_MessageHandler_0_2 ppp_message_handler_if_; |
171 | 173 |
172 // is_registered_ is only read/written on the main thread. | 174 // is_registered_ is only read/written on the main thread. |
173 bool is_registered_; | 175 bool is_registered_; |
174 | 176 |
175 // errors_ is written on the MessageHandler thread. When Destroy() is | 177 // errors_ is written on the MessageHandler thread. When Destroy() is |
176 // called, we stop writing to errors_ and signal destroy_event_. This causes | 178 // called, we stop writing to errors_ and signal destroy_event_. This causes |
177 // a memory barrier, so it's safe to read errors_ after that. | 179 // a memory barrier, so it's safe to read errors_ after that. |
178 std::string errors_; | 180 std::string errors_; |
179 NestedEvent test_finished_event_; | 181 NestedEvent test_finished_event_; |
180 NestedEvent destroy_event_; | 182 NestedEvent destroy_event_; |
181 | 183 |
182 // Undefined & private to disallow copy and assign. | 184 // Undefined & private to disallow copy and assign. |
183 EchoingMessageHandler(const EchoingMessageHandler&); | 185 EchoingMessageHandler(const EchoingMessageHandler&); |
184 EchoingMessageHandler& operator=(const EchoingMessageHandler&); | 186 EchoingMessageHandler& operator=(const EchoingMessageHandler&); |
185 }; | 187 }; |
186 | 188 |
187 void FakeHandleMessage(PP_Instance instance, | 189 void FakeHandleMessage(PP_Instance instance, |
188 void* user_data, | 190 void* user_data, |
189 struct PP_Var message_data) {} | 191 const PP_Var* message_data) {} |
190 PP_Var FakeHandleBlockingMessage(PP_Instance instance, | 192 void FakeHandleBlockingMessage(PP_Instance instance, |
191 void* user_data, | 193 void* user_data, |
192 struct PP_Var message_data) { | 194 const PP_Var* message_data, |
193 return PP_MakeUndefined(); | 195 PP_Var* result) {} |
194 } | |
195 void FakeDestroy(PP_Instance instance, void* user_data) {} | 196 void FakeDestroy(PP_Instance instance, void* user_data) {} |
196 | 197 |
197 } // namespace | 198 } // namespace |
198 | 199 |
199 TestMessageHandler::TestMessageHandler(TestingInstance* instance) | 200 TestMessageHandler::TestMessageHandler(TestingInstance* instance) |
200 : TestCase(instance), | 201 : TestCase(instance), |
201 ppb_messaging_if_(NULL), | 202 ppb_messaging_if_(NULL), |
202 handler_thread_(instance) { | 203 handler_thread_(instance) { |
203 } | 204 } |
204 | 205 |
205 TestMessageHandler::~TestMessageHandler() { | 206 TestMessageHandler::~TestMessageHandler() { |
206 handler_thread_.Join(); | 207 handler_thread_.Join(); |
207 } | 208 } |
208 | 209 |
209 bool TestMessageHandler::Init() { | 210 bool TestMessageHandler::Init() { |
210 ppb_messaging_if_ = static_cast<const PPB_Messaging_1_1*>( | 211 ppb_messaging_if_ = static_cast<const PPB_Messaging_1_2*>( |
211 pp::Module::Get()->GetBrowserInterface(PPB_MESSAGING_INTERFACE_1_1)); | 212 pp::Module::Get()->GetBrowserInterface(PPB_MESSAGING_INTERFACE_1_2)); |
212 return ppb_messaging_if_ && | 213 return ppb_messaging_if_ && |
213 CheckTestingInterface() && | 214 CheckTestingInterface() && |
214 handler_thread_.Start(); | 215 handler_thread_.Start(); |
215 } | 216 } |
216 | 217 |
217 void TestMessageHandler::RunTests(const std::string& filter) { | 218 void TestMessageHandler::RunTests(const std::string& filter) { |
218 RUN_TEST(RegisterErrorConditions, filter); | 219 RUN_TEST(RegisterErrorConditions, filter); |
219 RUN_TEST(PostMessageAndAwaitResponse, filter); | 220 RUN_TEST(PostMessageAndAwaitResponse, filter); |
220 } | 221 } |
221 | 222 |
222 void TestMessageHandler::HandleMessage(const pp::Var& message_data) { | 223 void TestMessageHandler::HandleMessage(const pp::Var& message_data) { |
223 // All messages should go to the background thread message handler. | 224 // All messages should go to the background thread message handler. |
224 assert(false); | 225 assert(false); |
225 } | 226 } |
226 | 227 |
227 std::string TestMessageHandler::TestRegisterErrorConditions() { | 228 std::string TestMessageHandler::TestRegisterErrorConditions() { |
228 { | 229 { |
229 // Test registering with the main thread as the message loop. | 230 // Test registering with the main thread as the message loop. |
230 PPP_MessageHandler_0_1 fake_ppp_message_handler = { | 231 PPP_MessageHandler_0_2 fake_ppp_message_handler = { |
231 &FakeHandleMessage, &FakeHandleBlockingMessage, &FakeDestroy | 232 &FakeHandleMessage, &FakeHandleBlockingMessage, &FakeDestroy |
232 }; | 233 }; |
233 pp::MessageLoop main_loop = pp::MessageLoop::GetForMainThread(); | 234 pp::MessageLoop main_loop = pp::MessageLoop::GetForMainThread(); |
234 int32_t result = ppb_messaging_if_->RegisterMessageHandler( | 235 int32_t result = ppb_messaging_if_->RegisterMessageHandler( |
235 instance()->pp_instance(), | 236 instance()->pp_instance(), |
236 reinterpret_cast<void*>(0xdeadbeef), | 237 reinterpret_cast<void*>(0xdeadbeef), |
237 &fake_ppp_message_handler, | 238 &fake_ppp_message_handler, |
238 main_loop.pp_resource()); | 239 main_loop.pp_resource()); |
239 ASSERT_EQ(PP_ERROR_WRONG_THREAD, result); | 240 ASSERT_EQ(PP_ERROR_WRONG_THREAD, result); |
240 } | 241 } |
241 { | 242 { |
242 // Test registering with incomplete PPP_Messaging interface. | 243 // Test registering with incomplete PPP_Messaging interface. |
243 PPP_MessageHandler_0_1 bad_ppp_ifs[] = { | 244 PPP_MessageHandler_0_2 bad_ppp_ifs[] = { |
244 { NULL, &FakeHandleBlockingMessage, &FakeDestroy }, | 245 { NULL, &FakeHandleBlockingMessage, &FakeDestroy }, |
245 { &FakeHandleMessage, NULL, &FakeDestroy }, | 246 { &FakeHandleMessage, NULL, &FakeDestroy }, |
246 { &FakeHandleMessage, &FakeHandleBlockingMessage, NULL }}; | 247 { &FakeHandleMessage, &FakeHandleBlockingMessage, NULL }}; |
247 for (size_t i = 0; i < sizeof(bad_ppp_ifs)/sizeof(bad_ppp_ifs[0]); ++i) { | 248 for (size_t i = 0; i < sizeof(bad_ppp_ifs)/sizeof(bad_ppp_ifs[0]); ++i) { |
248 int32_t result = ppb_messaging_if_->RegisterMessageHandler( | 249 int32_t result = ppb_messaging_if_->RegisterMessageHandler( |
249 instance()->pp_instance(), | 250 instance()->pp_instance(), |
250 reinterpret_cast<void*>(0xdeadbeef), | 251 reinterpret_cast<void*>(0xdeadbeef), |
251 &bad_ppp_ifs[i], | 252 &bad_ppp_ifs[i], |
252 handler_thread_.message_loop().pp_resource()); | 253 handler_thread_.message_loop().pp_resource()); |
253 ASSERT_EQ(PP_ERROR_BADARGUMENT, result); | 254 ASSERT_EQ(PP_ERROR_BADARGUMENT, result); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 // That should be fixed before this API goes to stable. See crbug.com/384528 | 289 // That should be fixed before this API goes to stable. See crbug.com/384528 |
289 js_code += "plugin.postMessage('FINISHED_TEST');\n"; | 290 js_code += "plugin.postMessage('FINISHED_TEST');\n"; |
290 instance_->EvalScript(js_code); | 291 instance_->EvalScript(js_code); |
291 handler.WaitForTestFinishedMessage(); | 292 handler.WaitForTestFinishedMessage(); |
292 handler.Unregister(); | 293 handler.Unregister(); |
293 ASSERT_SUBTEST_SUCCESS(handler.WaitForDestroy()); | 294 ASSERT_SUBTEST_SUCCESS(handler.WaitForDestroy()); |
294 | 295 |
295 PASS(); | 296 PASS(); |
296 } | 297 } |
297 | 298 |
OLD | NEW |