15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 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)#include "ppapi/tests/test_post_message.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <map> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sstream> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/dev/ppb_testing_dev.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_var.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/instance.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/var.h" 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ppapi/cpp/var_array.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/var_array_buffer.h" 17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ppapi/cpp/var_dictionary.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/tests/pp_thread.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/tests/test_utils.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/tests/testing_instance.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Windows defines 'PostMessage', so we have to undef it. 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PostMessage 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef PostMessage 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)REGISTER_TEST_CASE(PostMessage); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kTestString[] = "Hello world!"; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const bool kTestBool = true; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int32_t kTestInt = 42; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const double kTestDouble = 42.0; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// On Windows XP bots, the NonMainThread test can run very slowly. So we dial 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// back the number of threads & messages when running on Windows. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef PPAPI_OS_WIN 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int32_t kThreadsToRun = 2; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int32_t kMessagesToSendPerThread = 5; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int32_t kThreadsToRun = 4; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int32_t kMessagesToSendPerThread = 10; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The struct that invoke_post_message_thread_func expects for its argument. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It includes the instance on which to invoke PostMessage, and the value to 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// pass to PostMessage. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct InvokePostMessageThreadArg { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InvokePostMessageThreadArg(pp::Instance* i, const pp::Var& v) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : instance(i), value_to_send(v) {} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Instance* instance; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Var value_to_send; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InvokePostMessageThreadFunc(void* user_data) { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InvokePostMessageThreadArg* arg = 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<InvokePostMessageThreadArg*>(user_data); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int32_t i = 0; i < kMessagesToSendPerThread; ++i) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) arg->instance->PostMessage(arg->value_to_send); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete arg; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// TODO(raymes): Consider putting something like this into pp::Var. 6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool VarsEqual(const pp::Var& expected, 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const pp::Var& actual, 6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::map<int64_t, int64_t>* visited_ids) { 6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (expected.pp_var().type != actual.pp_var().type) { 6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!expected.is_number() && !actual.is_number()) 7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // TODO(raymes): Implement a pp::Var::IsRefCounted() function. 7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (expected.pp_var().type > PP_VARTYPE_DOUBLE) { 7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::map<int64_t, int64_t>::const_iterator it = 7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) visited_ids->find(expected.pp_var().value.as_id); 7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (it != visited_ids->end()) { 7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (it->second == actual.pp_var().value.as_id) 7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return true; 7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) (*visited_ids)[expected.pp_var().value.as_id] = actual.pp_var().value.as_id; 8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (expected.is_number()) { 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return fabs(expected.AsDouble() - actual.AsDouble()) < 1.0e-4; 8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else if (expected.is_array()) { 87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp::VarArray expected_array(expected); 88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp::VarArray actual_array(actual); 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (expected_array.GetLength() != actual_array.GetLength()) 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (uint32_t i = 0; i < expected_array.GetLength(); ++i) { 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!VarsEqual(expected_array.Get(i), actual_array.Get(i), visited_ids)) 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return true; 9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else if (expected.is_dictionary()) { 97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp::VarDictionary expected_dict(expected); 98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp::VarDictionary actual_dict(actual); 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (expected_dict.GetKeys().GetLength() != 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) actual_dict.GetKeys().GetLength()) { 10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (uint32_t i = 0; i < expected_dict.GetKeys().GetLength(); ++i) { 10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) pp::Var key = expected_dict.GetKeys().Get(i); 105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!actual_dict.HasKey(key)) 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!VarsEqual(expected_dict.Get(key), actual_dict.Get(key), visited_ids)) 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return true; 11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else { 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return expected == actual; 11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool VarsEqual(const pp::Var& expected, 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const pp::Var& actual) { 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::map<int64_t, int64_t> visited_ids; 11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return VarsEqual(expected, actual, &visited_ids); 12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class ScopedArrayBufferSizeSetter { 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ScopedArrayBufferSizeSetter(const PPB_Testing_Dev* interface, 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PP_Instance instance, 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint32_t threshold) 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : interface_(interface), 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) instance_(instance) { 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) interface_->SetMinimumArrayBufferSizeForShmem(instance_, threshold); 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ~ScopedArrayBufferSizeSetter() { 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) interface_->SetMinimumArrayBufferSizeForShmem(instance_, 0); 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const PPB_Testing_Dev* interface_; 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PP_Instance instance_; 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FINISHED_WAITING_MESSAGE "TEST_POST_MESSAGE_FINISHED_WAITING" 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TestPostMessage::TestPostMessage(TestingInstance* instance) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : TestCase(instance) { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TestPostMessage::~TestPostMessage() { 148ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch instance_->PostMessage(pp::Var("This isn't guaranteed to be received, but " 149ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch "shouldn't cause a crash.")); 150ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remove the special listener that only responds to a FINISHED_WAITING 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // string. See Init for where it gets added. 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string js_code; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) js_code += "var plugin = document.getElementById('plugin');" 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "plugin.removeEventListener('message'," 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " plugin.wait_for_messages_handler);" 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "delete plugin.wait_for_messages_handler;"; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->EvalScript(js_code); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestPostMessage::Init() { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success = CheckTestingInterface(); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set up a special listener that only responds to a FINISHED_WAITING string. 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is for use by WaitForMessages. 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string js_code; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note the following code is dependent on some features of test_case.html. 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // E.g., it is assumed that the DOM element where the plugin is embedded has 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // an id of 'plugin', and there is a function 'IsTestingMessage' that allows 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // us to ignore the messages that are intended for use by the testing 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // framework itself. 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) js_code += "var plugin = document.getElementById('plugin');" 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "var wait_for_messages_handler = function(message_event) {" 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " if (!IsTestingMessage(message_event.data) &&" 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " message_event.data === '" FINISHED_WAITING_MESSAGE "') {" 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " plugin.postMessage('" FINISHED_WAITING_MESSAGE "');" 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " }" 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "};" 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "plugin.addEventListener('message', wait_for_messages_handler);" 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stash it on the plugin so we can remove it in the destructor. 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "plugin.wait_for_messages_handler = wait_for_messages_handler;"; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->EvalScript(js_code); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set up the JavaScript message event listener to echo the data part of the 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // message event back to us. 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) success = success && AddEchoingListener("message_event.data"); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_data_.clear(); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send a message that the first test will expect to receive. This is to 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // verify that we can send messages when the 'Instance::Init' function is on 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the stack. 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->PostMessage(pp::Var(kTestString)); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return success; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestPostMessage::RunTests(const std::string& filter) { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: SendInInit must be first, because it expects to receive a message 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that was sent in Init above. 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST(SendInInit, filter); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST(SendingData, filter); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST(SendingArrayBuffer, filter); 20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RUN_TEST(SendingArray, filter); 20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RUN_TEST(SendingDictionary, filter); 20490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RUN_TEST(SendingComplexVar, filter); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST(MessageEvent, filter); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST(NoHandler, filter); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST(ExtraParam, filter); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (testing_interface_->IsOutOfProcess()) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST(NonMainThread, filter); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestPostMessage::HandleMessage(const pp::Var& message_data) { 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (message_data.is_string() && 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (message_data.AsString() == FINISHED_WAITING_MESSAGE)) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testing_interface_->QuitMessageLoop(instance_->pp_instance()); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_data_.push_back(message_data); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestPostMessage::AddEchoingListener(const std::string& expression) { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string js_code; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note the following code is dependent on some features of test_case.html. 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // E.g., it is assumed that the DOM element where the plugin is embedded has 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // an id of 'plugin', and there is a function 'IsTestingMessage' that allows 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // us to ignore the messages that are intended for use by the testing 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // framework itself. 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) js_code += "var plugin = document.getElementById('plugin');" 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "var message_handler = function(message_event) {" 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " if (!IsTestingMessage(message_event.data) &&" 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " !(message_event.data === '" FINISHED_WAITING_MESSAGE "')) {" 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " plugin.postMessage("; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) js_code += expression; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) js_code += " );" 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " }" 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "};" 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "plugin.addEventListener('message', message_handler);" 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Maintain an array of all event listeners, attached to the 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // plugin. This is so that we can easily remove them later (see 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ClearListeners()). 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "if (!plugin.eventListeners) plugin.eventListeners = [];" 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "plugin.eventListeners.push(message_handler);"; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->EvalScript(js_code); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool TestPostMessage::PostMessageFromJavaScript(const std::string& func) { 2477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) std::string js_code; 2487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) js_code += "var plugin = document.getElementById('plugin');" 2497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) "plugin.postMessage("; 2507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) js_code += func + "()"; 2517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) js_code += " );"; 2527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) instance_->EvalScript(js_code); 2537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return true; 2547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestPostMessage::ClearListeners() { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string js_code; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) js_code += "var plugin = document.getElementById('plugin');" 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "while (plugin.eventListeners.length) {" 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " plugin.removeEventListener('message'," 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " plugin.eventListeners.pop());" 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}"; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->EvalScript(js_code); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int TestPostMessage::WaitForMessages() { 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t message_size_before = message_data_.size(); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We first post a FINISHED_WAITING_MESSAGE. This should be guaranteed to 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // come back _after_ any other incoming messages that were already pending. 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->PostMessage(pp::Var(FINISHED_WAITING_MESSAGE)); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testing_interface_->RunMessageLoop(instance_->pp_instance()); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now that the FINISHED_WAITING_MESSAGE has been echoed back to us, we know 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that all pending messages have been slurped up. Return the number we 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // received (which may be zero). 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return message_data_.size() - message_size_before; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::string TestPostMessage::CheckMessageProperties( 28090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const pp::Var& test_data, 28190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::vector<std::string>& properties_to_check) { 28290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) typedef std::vector<std::string>::const_iterator Iterator; 28390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (Iterator iter = properties_to_check.begin(); 28490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) iter != properties_to_check.end(); 28590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ++iter) { 28690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(AddEchoingListener(*iter)); 28790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) message_data_.clear(); 28890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) instance_->PostMessage(test_data); 28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_EQ(message_data_.size(), 0); 29090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_EQ(WaitForMessages(), 1); 29190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(message_data_.back().is_bool()); 29290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!message_data_.back().AsBool()) 29390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return std::string("Failed: ") + *iter; 29490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(message_data_.back().AsBool()); 29590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(ClearListeners()); 29690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 29790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PASS(); 29890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 29990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestPostMessage::TestSendInInit() { 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WaitForMessages(), 1); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This test assumes Init already sent a message. 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(message_data_.size(), 1); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(message_data_.back().is_string()); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(message_data_.back().AsString(), kTestString); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_data_.clear(); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestPostMessage::TestSendingData() { 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clean up after previous tests. This also swallows the message sent by Init 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if we didn't run the 'SendInInit' test. All tests other than 'SendInInit' 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // should start with these. 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForMessages(); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ClearListeners()); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set up the JavaScript message event listener to echo the data part of the 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // message event back to us. 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(AddEchoingListener("message_event.data")); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test sending a message to JavaScript for each supported type. The JS sends 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the data back to us, and we check that they match. 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_data_.clear(); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->PostMessage(pp::Var(kTestString)); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // PostMessage is asynchronous, so we should not receive a response yet. 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(message_data_.size(), 0); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WaitForMessages(), 1); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(message_data_.back().is_string()); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(message_data_.back().AsString(), kTestString); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_data_.clear(); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->PostMessage(pp::Var(kTestBool)); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(message_data_.size(), 0); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WaitForMessages(), 1); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(message_data_.back().is_bool()); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(message_data_.back().AsBool(), kTestBool); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_data_.clear(); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->PostMessage(pp::Var(kTestInt)); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(message_data_.size(), 0); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WaitForMessages(), 1); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(message_data_.back().is_number()); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_DOUBLE_EQ(message_data_.back().AsDouble(), 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<double>(kTestInt)); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_data_.clear(); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->PostMessage(pp::Var(kTestDouble)); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(message_data_.size(), 0); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WaitForMessages(), 1); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(message_data_.back().is_number()); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_DOUBLE_EQ(message_data_.back().AsDouble(), kTestDouble); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_data_.clear(); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->PostMessage(pp::Var()); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(message_data_.size(), 0); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WaitForMessages(), 1); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(message_data_.back().is_undefined()); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_data_.clear(); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->PostMessage(pp::Var(pp::Var::Null())); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(message_data_.size(), 0); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WaitForMessages(), 1); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(message_data_.back().is_null()); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_data_.clear(); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ClearListeners()); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestPostMessage::TestSendingArrayBuffer() { 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clean up after previous tests. This also swallows the message sent by Init 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if we didn't run the 'SendInInit' test. All tests other than 'SendInInit' 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // should start with these. 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForMessages(); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ClearListeners()); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(sehr,dmichael): Add testing of longer array buffers when 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // crbug.com/110086 is fixed. 379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ScopedArrayBufferSizeSetter setter(testing_interface_, 380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) instance_->pp_instance(), 381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 200); 382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint32_t sizes[] = { 0, 100, 1000, 10000 }; 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < sizeof(sizes)/sizeof(sizes[i]); ++i) { 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::ostringstream size_stream; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_stream << sizes[i]; 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kSizeAsString(size_stream.str()); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create an appropriately sized array buffer with test_data[i] == i. 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::VarArrayBuffer test_data(sizes[i]); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sizes[i] > 0) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NE(NULL, test_data.Map()); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure we can Unmap/Map successfully (there's not really any way to 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // detect if it's unmapped, so we just re-map before getting the pointer to 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the buffer). 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_data.Unmap(); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_data.Map(); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(sizes[i], test_data.ByteLength()); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char* buff = static_cast<unsigned char*>(test_data.Map()); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint32_t kByteLength = test_data.ByteLength(); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t j = 0; j < kByteLength; ++j) 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buff[j] = static_cast<uint8_t>(j % 256u); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Have the listener test some properties of the ArrayBuffer. 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string> properties_to_check; 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) properties_to_check.push_back( 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "message_event.data.constructor.name === 'ArrayBuffer'"); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) properties_to_check.push_back( 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string("message_event.data.byteLength === ") + kSizeAsString); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sizes[i] > 0) { 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) properties_to_check.push_back( 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "(new DataView(message_event.data)).getUint8(0) == 0"); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Checks that the last element has the right value: (byteLength-1)%256. 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string received_byte("(new DataView(message_event.data)).getUint8(" 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " message_event.data.byteLength-1)"); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string expected_byte("(message_event.data.byteLength-1)%256"); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) properties_to_check.push_back(received_byte + " == " + expected_byte); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_SUBTEST_SUCCESS(CheckMessageProperties(test_data, 41990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) properties_to_check)); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set up the JavaScript message event listener to echo the data part of the 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // message event back to us. 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(AddEchoingListener("message_event.data")); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_data_.clear(); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->PostMessage(test_data); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // PostMessage is asynchronous, so we should not receive a response yet. 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(message_data_.size(), 0); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WaitForMessages(), 1); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(message_data_.back().is_array_buffer()); 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::VarArrayBuffer received(message_data_.back()); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_data_.clear(); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(test_data.ByteLength(), received.ByteLength()); 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char* received_buff = static_cast<unsigned char*>(received.Map()); 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The buffer should be copied, so this should be a distinct buffer. When 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 'transferrables' are implemented for PPAPI, we'll also want to test that 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we get the _same_ buffer back when it's transferred. 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sizes[i] > 0) 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NE(buff, received_buff); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < test_data.ByteLength(); ++i) 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(buff[i], received_buff[i]); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_data_.clear(); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ClearListeners()); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 44890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 44990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::string TestPostMessage::TestSendingArray() { 45090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Clean up after previous tests. This also swallows the message sent by Init 45190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // if we didn't run the 'SendInInit' test. All tests other than 'SendInInit' 45290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // should start with these. 45390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WaitForMessages(); 45490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(ClearListeners()); 45590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 456eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp::VarArray array; 45790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) array.Set(0, pp::Var(kTestBool)); 45890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) array.Set(1, pp::Var(kTestString)); 45990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Purposely leave index 2 empty. 46090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) array.Set(3, pp::Var(kTestInt)); 46190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) array.Set(4, pp::Var(kTestDouble)); 46290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 46390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::stringstream ss; 46490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ss << array.GetLength(); 46590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string length_as_string(ss.str()); 46690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 46790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Have the listener test some properties of the Array. 46890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<std::string> properties_to_check; 46990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) properties_to_check.push_back( 47090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "message_event.data.constructor.name === 'Array'"); 47190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) properties_to_check.push_back( 47290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string("message_event.data.length === ") + length_as_string); 47390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_SUBTEST_SUCCESS(CheckMessageProperties(array, properties_to_check)); 47490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 47590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Set up the JavaScript message event listener to echo the data part of the 47690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // message event back to us. 47790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(AddEchoingListener("message_event.data")); 47890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) message_data_.clear(); 47990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) instance_->PostMessage(array); 48090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // PostMessage is asynchronous, so we should not receive a response yet. 48190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_EQ(message_data_.size(), 0); 48290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_EQ(WaitForMessages(), 1); 48390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(message_data_.back().is_array()); 48490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(VarsEqual(array, message_data_.back())); 48590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 48690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) message_data_.clear(); 48790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(ClearListeners()); 48890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 48990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PASS(); 49090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 49190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 49290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::string TestPostMessage::TestSendingDictionary() { 49390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Clean up after previous tests. This also swallows the message sent by Init 49490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // if we didn't run the 'SendInInit' test. All tests other than 'SendInInit' 49590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // should start with these. 49690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WaitForMessages(); 49790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(ClearListeners()); 49890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 499eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp::VarDictionary dictionary; 50090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dictionary.Set(pp::Var("foo"), pp::Var(kTestBool)); 50190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dictionary.Set(pp::Var("bar"), pp::Var(kTestString)); 50290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dictionary.Set(pp::Var("abc"), pp::Var(kTestInt)); 50390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dictionary.Set(pp::Var("def"), pp::Var()); 50490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 50590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::stringstream ss; 50690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ss << dictionary.GetKeys().GetLength(); 50790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string length_as_string(ss.str()); 50890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 50990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Have the listener test some properties of the Dictionary. 51090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<std::string> properties_to_check; 51190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) properties_to_check.push_back( 51290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "message_event.data.constructor.name === 'Object'"); 51390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) properties_to_check.push_back( 51490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string("Object.keys(message_event.data).length === ") + 51590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) length_as_string); 51690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_SUBTEST_SUCCESS(CheckMessageProperties(dictionary, 51790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) properties_to_check)); 51890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 51990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Set up the JavaScript message event listener to echo the data part of the 52090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // message event back to us. 52190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(AddEchoingListener("message_event.data")); 52290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) message_data_.clear(); 52390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) instance_->PostMessage(dictionary); 52490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // PostMessage is asynchronous, so we should not receive a response yet. 52590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_EQ(message_data_.size(), 0); 52690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_EQ(WaitForMessages(), 1); 52790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(message_data_.back().is_dictionary()); 52890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(VarsEqual(dictionary, message_data_.back())); 52990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 53090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) message_data_.clear(); 53190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(ClearListeners()); 53290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 53390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PASS(); 53490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 53590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 53690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::string TestPostMessage::TestSendingComplexVar() { 53790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Clean up after previous tests. This also swallows the message sent by Init 53890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // if we didn't run the 'SendInInit' test. All tests other than 'SendInInit' 53990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // should start with these. 54090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WaitForMessages(); 5417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) message_data_.clear(); 54290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(ClearListeners()); 54390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 54490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) pp::Var string(kTestString); 545eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp::VarDictionary dictionary; 54690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dictionary.Set(pp::Var("foo"), pp::Var(kTestBool)); 54790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dictionary.Set(pp::Var("bar"), string); 54890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dictionary.Set(pp::Var("abc"), pp::Var(kTestInt)); 54990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dictionary.Set(pp::Var("def"), pp::Var()); 55090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 55190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Reference to array. 552eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp::VarArray array; 55390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) array.Set(0, pp::Var(kTestBool)); 55490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) array.Set(1, string); 55590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Purposely leave index 2 empty (which will place an undefined var there). 55690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) array.Set(3, pp::Var(kTestInt)); 55790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) array.Set(4, pp::Var(kTestDouble)); 55890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 55990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dictionary.Set(pp::Var("array-ref1"), array); 56090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dictionary.Set(pp::Var("array-ref2"), array); 56190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 56290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Set up the JavaScript message event listener to echo the data part of the 56390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // message event back to us. 56490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(AddEchoingListener("message_event.data")); 56590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) instance_->PostMessage(dictionary); 56690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // PostMessage is asynchronous, so we should not receive a response yet. 56790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_EQ(message_data_.size(), 0); 56890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_EQ(WaitForMessages(), 1); 56990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(message_data_.back().is_dictionary()); 570eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp::VarDictionary result(message_data_.back()); 57190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(VarsEqual(dictionary, message_data_.back())); 57290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) WaitForMessages(); 5747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) message_data_.clear(); 5757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_TRUE(ClearListeners()); 5767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Set up a (dictionary -> array -> dictionary) cycle. Cycles shouldn't be 5787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // transmitted. 579eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp::VarArray array2; 5807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) array2.Set(0, dictionary); 5817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) dictionary.Set(pp::Var("array2"), array2); 5827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_TRUE(AddEchoingListener("message_event.data")); 5847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) instance_->PostMessage(dictionary); 5857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // PostMessage is asynchronous, so we should not receive a response yet. 5867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_EQ(message_data_.size(), 0); 5877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_EQ(WaitForMessages(), 0); 5887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 58990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Break the cycles. 59090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dictionary.Delete(pp::Var("array2")); 59190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) WaitForMessages(); 5937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) message_data_.clear(); 5947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_TRUE(ClearListeners()); 5957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Test sending a cycle from JavaScript to the plugin. 5977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_TRUE(AddEchoingListener("message_event.data")); 5987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PostMessageFromJavaScript("function() { var x = []; x[0] = x; return x; }"); 5997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_EQ(message_data_.size(), 0); 6007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_EQ(WaitForMessages(), 0); 6017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 6027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) WaitForMessages(); 60390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) message_data_.clear(); 60490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(ClearListeners()); 60590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 60690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PASS(); 60790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestPostMessage::TestMessageEvent() { 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set up the JavaScript message event listener to pass us some values from 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the MessageEvent and make sure they match our expectations. 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForMessages(); 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ClearListeners()); 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Have the listener pass back the class name of message_event and make sure 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it's "MessageEvent". 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(AddEchoingListener("message_event.constructor.name")); 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_data_.clear(); 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->PostMessage(pp::Var(kTestInt)); 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(message_data_.size(), 0); 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WaitForMessages(), 1); 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(message_data_.back().is_string()); 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(message_data_.back().AsString(), "MessageEvent"); 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ClearListeners()); 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure all the non-data properties have the expected values. 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success = AddEchoingListener("((message_event.origin === '')" 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " && (message_event.lastEventId === '')" 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " && (message_event.source === null)" 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " && (message_event.ports.length === 0)" 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " && (message_event.bubbles === false)" 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " && (message_event.cancelable === false)" 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ")"); 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(success); 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_data_.clear(); 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->PostMessage(pp::Var(kTestInt)); 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(message_data_.size(), 0); 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WaitForMessages(), 1); 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(message_data_.back().is_bool()); 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(message_data_.back().AsBool()); 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ClearListeners()); 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add some event handlers to make sure they receive messages. 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(AddEchoingListener("1")); 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(AddEchoingListener("2")); 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(AddEchoingListener("3")); 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_data_.clear(); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->PostMessage(pp::Var(kTestInt)); 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure we don't get a response in a re-entrant fashion. 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(message_data_.size(), 0); 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should get 3 messages. 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WaitForMessages(), 3); 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Copy to a vector of doubles and sort; w3c does not specify the order for 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // event listeners. (Copying is easier than writing an operator< for pp::Var.) 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html. 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VarVector::iterator iter(message_data_.begin()), the_end(message_data_.end()); 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<double> double_vec; 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (; iter != the_end; ++iter) { 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(iter->is_number()); 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double_vec.push_back(iter->AsDouble()); 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::sort(double_vec.begin(), double_vec.end()); 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_DOUBLE_EQ(double_vec[0], 1.0); 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_DOUBLE_EQ(double_vec[1], 2.0); 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_DOUBLE_EQ(double_vec[2], 3.0); 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_data_.clear(); 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ClearListeners()); 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestPostMessage::TestNoHandler() { 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delete any lingering messages and event listeners. 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForMessages(); 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ClearListeners()); 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now send a message. We shouldn't get a response. 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_data_.clear(); 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->PostMessage(pp::Var()); 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WaitForMessages(), 0); 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(message_data_.empty()); 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestPostMessage::TestExtraParam() { 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delete any lingering messages and event listeners. 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForMessages(); 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ClearListeners()); 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add a listener that will respond with 1 and an empty array (where the 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // message port array would appear if it was Worker postMessage). 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(AddEchoingListener("1, []")); 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now send a message. We shouldn't get a response. 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_data_.clear(); 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->PostMessage(pp::Var()); 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WaitForMessages(), 0); 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(message_data_.empty()); 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ClearListeners()); 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestPostMessage::TestNonMainThread() { 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForMessages(); 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ClearListeners()); 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(AddEchoingListener("message_event.data")); 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_data_.clear(); 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set up a thread for each integer from 0 to (kThreadsToRun - 1). Make each 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread send the number that matches its index kMessagesToSendPerThread 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // times. For good measure, call postMessage from the main thread 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // kMessagesToSendPerThread times. At the end, we make sure we got all the 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // values we expected. 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_ThreadType threads[kThreadsToRun]; 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int32_t i = 0; i < kThreadsToRun; ++i) { 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set up a thread to send a value of i. 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* arg = new InvokePostMessageThreadArg(instance_, pp::Var(i)); 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_CreateThread(&threads[i], &InvokePostMessageThreadFunc, arg); 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Invoke PostMessage right now to send a value of (kThreadsToRun). 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int32_t i = 0; i < kMessagesToSendPerThread; ++i) 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->PostMessage(pp::Var(kThreadsToRun)); 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now join all threads. 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int32_t i = 0; i < kThreadsToRun; ++i) 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_JoinThread(threads[i]); 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // PostMessage is asynchronous, so we should not receive a response yet. 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(message_data_.size(), 0); 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure we got all values that we expected. Note that because it's legal 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for the JavaScript engine to treat our integers as floating points, we 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // can't just use std::find or equality comparison. So we instead, we convert 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // each incoming value to an integer, and count them in received_counts. 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t expected_num = (kThreadsToRun + 1) * kMessagesToSendPerThread; 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Count how many we receive per-index. 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<int32_t> expected_counts(kThreadsToRun + 1, 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kMessagesToSendPerThread); 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<int32_t> received_counts(kThreadsToRun + 1, 0); 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WaitForMessages(), expected_num); 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int32_t i = 0; i < expected_num; ++i) { 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const pp::Var& latest_var(message_data_[i]); 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(latest_var.is_int() || latest_var.is_double()); 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t received_value = -1; 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (latest_var.is_int()) { 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) received_value = latest_var.AsInt(); 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (latest_var.is_double()) { 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) received_value = static_cast<int32_t>(latest_var.AsDouble() + 0.5); 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(received_value >= 0); 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(received_value <= kThreadsToRun); 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++received_counts[received_value]; 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(received_counts, expected_counts); 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_data_.clear(); 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ClearListeners()); 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 766