| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_post_message.h" | 5 #include "ppapi/tests/test_post_message.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> |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 275 // We first post a FINISHED_WAITING_MESSAGE. This should be guaranteed to | 275 // We first post a FINISHED_WAITING_MESSAGE. This should be guaranteed to |
| 276 // come back _after_ any other incoming messages that were already pending. | 276 // come back _after_ any other incoming messages that were already pending. |
| 277 instance_->PostMessage(pp::Var(FINISHED_WAITING_MESSAGE)); | 277 instance_->PostMessage(pp::Var(FINISHED_WAITING_MESSAGE)); |
| 278 testing_interface_->RunMessageLoop(instance_->pp_instance()); | 278 testing_interface_->RunMessageLoop(instance_->pp_instance()); |
| 279 // Now that the FINISHED_WAITING_MESSAGE has been echoed back to us, we know | 279 // Now that the FINISHED_WAITING_MESSAGE has been echoed back to us, we know |
| 280 // that all pending messages have been slurped up. Return the number we | 280 // that all pending messages have been slurped up. Return the number we |
| 281 // received (which may be zero). | 281 // received (which may be zero). |
| 282 return message_data_.size() - message_size_before; | 282 return message_data_.size() - message_size_before; |
| 283 } | 283 } |
| 284 | 284 |
| 285 int TestPostMessage::PostAsyncMessageFromJavaScriptAndWait( | |
| 286 const std::string& func) { | |
| 287 // After the |func| calls callback, post both the given |message|, as well as | |
| 288 // the special message FINISHED_WAITING_MESSAGE. This ensures that | |
| 289 // RunMessageLoop correctly waits until the callback is called. | |
| 290 std::string js_code; | |
| 291 js_code += "var plugin = document.getElementById('plugin');" | |
| 292 "var callback = function(message) {" | |
| 293 " plugin.postMessage(message);" | |
| 294 " plugin.postMessage('" FINISHED_WAITING_MESSAGE "');" | |
| 295 "};"; | |
| 296 js_code += "(" + func + ")(callback);"; | |
| 297 instance_->EvalScript(js_code); | |
| 298 | |
| 299 size_t message_size_before = message_data_.size(); | |
| 300 // Unlike WaitForMessages, we do not post FINISHED_WAITING_MESSAGE. This is | |
| 301 // because the above JavaScript code will post it for us, when the | |
| 302 // asynchronous operation completes. | |
| 303 testing_interface_->RunMessageLoop(instance_->pp_instance()); | |
| 304 // Now that the FINISHED_WAITING_MESSAGE has been echoed back to us, we know | |
| 305 // that all pending messages have been slurped up. Return the number we | |
| 306 // received (which may be zero). | |
| 307 return message_data_.size() - message_size_before; | |
| 308 } | |
| 309 | |
| 310 std::string TestPostMessage::CheckMessageProperties( | 285 std::string TestPostMessage::CheckMessageProperties( |
| 311 const pp::Var& test_data, | 286 const pp::Var& test_data, |
| 312 const std::vector<std::string>& properties_to_check) { | 287 const std::vector<std::string>& properties_to_check) { |
| 313 typedef std::vector<std::string>::const_iterator Iterator; | 288 typedef std::vector<std::string>::const_iterator Iterator; |
| 314 for (Iterator iter = properties_to_check.begin(); | 289 for (Iterator iter = properties_to_check.begin(); |
| 315 iter != properties_to_check.end(); | 290 iter != properties_to_check.end(); |
| 316 ++iter) { | 291 ++iter) { |
| 317 ASSERT_TRUE(AddEchoingListener(*iter)); | 292 ASSERT_TRUE(AddEchoingListener(*iter)); |
| 318 message_data_.clear(); | 293 message_data_.clear(); |
| 319 instance_->PostMessage(test_data); | 294 instance_->PostMessage(test_data); |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 565 } | 540 } |
| 566 | 541 |
| 567 std::string TestPostMessage::TestSendingResource() { | 542 std::string TestPostMessage::TestSendingResource() { |
| 568 // Clean up after previous tests. This also swallows the message sent by Init | 543 // Clean up after previous tests. This also swallows the message sent by Init |
| 569 // if we didn't run the 'SendInInit' test. All tests other than 'SendInInit' | 544 // if we didn't run the 'SendInInit' test. All tests other than 'SendInInit' |
| 570 // should start with these. | 545 // should start with these. |
| 571 WaitForMessages(); | 546 WaitForMessages(); |
| 572 message_data_.clear(); | 547 message_data_.clear(); |
| 573 ASSERT_TRUE(ClearListeners()); | 548 ASSERT_TRUE(ClearListeners()); |
| 574 | 549 |
| 575 // Test sending a DOMFileSystem from JavaScript to the plugin. | 550 std::string file_path("/"); |
| 576 // This opens a real (temporary) file using the HTML5 FileSystem API and | 551 file_path += kTestFilename; |
| 577 // writes to it. | 552 int content_length = strlen(kTestString); |
| 553 |
| 554 // Create a file in the HTML5 temporary file system, in the Pepper plugin. |
| 555 TestCompletionCallback callback(instance_->pp_instance(), callback_type()); |
| 556 pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY); |
| 557 callback.WaitForResult(file_system.Open(1024, callback.GetCallback())); |
| 558 CHECK_CALLBACK_BEHAVIOR(callback); |
| 559 ASSERT_EQ(PP_OK, callback.result()); |
| 560 pp::FileRef write_file_ref(file_system, file_path.c_str()); |
| 561 // Write to the file. |
| 562 pp::FileIO write_file_io(instance_); |
| 563 ASSERT_NE(0, write_file_io.pp_resource()); |
| 564 callback.WaitForResult( |
| 565 write_file_io.Open(write_file_ref, |
| 566 PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_CREATE, |
| 567 callback.GetCallback())); |
| 568 CHECK_CALLBACK_BEHAVIOR(callback); |
| 569 ASSERT_EQ(PP_OK, callback.result()); |
| 570 callback.WaitForResult(write_file_io.Write( |
| 571 0, kTestString, content_length, callback.GetCallback())); |
| 572 CHECK_CALLBACK_BEHAVIOR(callback); |
| 573 ASSERT_EQ(callback.result(), content_length); |
| 574 write_file_io.Close(); |
| 575 |
| 576 // Pass the file system to JavaScript and have the listener test some |
| 577 // properties of the file system. |
| 578 pp::Var file_system_var(file_system); |
| 579 std::vector<std::string> properties_to_check; |
| 580 properties_to_check.push_back( |
| 581 "message_event.data.constructor.name === 'DOMFileSystem'"); |
| 582 properties_to_check.push_back( |
| 583 "message_event.data.root.constructor.name === 'DirectoryEntry'"); |
| 584 properties_to_check.push_back( |
| 585 "message_event.data.name.indexOf(" |
| 586 " ':Temporary'," |
| 587 " message_event.data.name.length - ':Temporary'.length) !== -1"); |
| 588 ASSERT_SUBTEST_SUCCESS(CheckMessageProperties(file_system_var, |
| 589 properties_to_check)); |
| 590 |
| 591 // Set up the JavaScript message event listener to echo the data part of the |
| 592 // message event back to us. |
| 578 ASSERT_TRUE(AddEchoingListener("message_event.data")); | 593 ASSERT_TRUE(AddEchoingListener("message_event.data")); |
| 594 // Send the file system in a message from the Pepper plugin to JavaScript. |
| 595 message_data_.clear(); |
| 596 instance_->PostMessage(file_system_var); |
| 597 // PostMessage is asynchronous, so we should not receive a response yet. |
| 579 ASSERT_EQ(0, message_data_.size()); | 598 ASSERT_EQ(0, message_data_.size()); |
| 580 std::string js_code = | 599 ASSERT_EQ(1, WaitForMessages()); |
| 581 "function(callback) {" | 600 |
| 582 " window.webkitRequestFileSystem(window.TEMPORARY, 1024," | 601 // The JavaScript should have posted the file system back to us. Verify that |
| 583 " function(fileSystem) {" | 602 // it is a file system and read the file contents that we wrote earlier. |
| 584 " fileSystem.root.getFile('"; | |
| 585 js_code += kTestFilename; | |
| 586 js_code += "', {create: true}, function(tempFile) {" | |
| 587 " tempFile.createWriter(function(writer) {" | |
| 588 " writer.onerror = function() { callback(null); };" | |
| 589 " writer.onwriteend = function() { callback(fileSystem); };" | |
| 590 " var blob = new Blob(['"; | |
| 591 js_code += kTestString; | |
| 592 js_code += "'], {'type': 'text/plain'});" | |
| 593 " writer.write(blob);" | |
| 594 " });" | |
| 595 " }, function() { callback(null); });" | |
| 596 " }, function() { callback(null); });" | |
| 597 "}"; | |
| 598 ASSERT_EQ(PostAsyncMessageFromJavaScriptAndWait(js_code), 1); | |
| 599 pp::Var var = message_data_.back(); | 603 pp::Var var = message_data_.back(); |
| 600 ASSERT_TRUE(var.is_resource()); | 604 ASSERT_TRUE(var.is_resource()); |
| 601 pp::Resource result = var.AsResource(); | 605 pp::Resource result = var.AsResource(); |
| 602 ASSERT_TRUE(pp::FileSystem::IsFileSystem(result)); | 606 ASSERT_TRUE(pp::FileSystem::IsFileSystem(result)); |
| 603 { | 607 { |
| 604 pp::FileSystem file_system(result); | 608 pp::FileSystem received_file_system(result); |
| 605 std::string file_path("/"); | 609 pp::FileRef file_ref(received_file_system, file_path.c_str()); |
| 606 file_path += kTestFilename; | |
| 607 pp::FileRef file_ref(file_system, file_path.c_str()); | |
| 608 ASSERT_NE(0, file_ref.pp_resource()); | 610 ASSERT_NE(0, file_ref.pp_resource()); |
| 609 | 611 |
| 610 // Ensure that the file can be queried. | 612 // Ensure that the file can be queried. |
| 611 TestCompletionCallbackWithOutput<PP_FileInfo> cc(instance_->pp_instance(), | 613 TestCompletionCallbackWithOutput<PP_FileInfo> cc(instance_->pp_instance(), |
| 612 callback_type()); | 614 callback_type()); |
| 613 cc.WaitForResult(file_ref.Query(cc.GetCallback())); | 615 cc.WaitForResult(file_ref.Query(cc.GetCallback())); |
| 614 CHECK_CALLBACK_BEHAVIOR(cc); | 616 CHECK_CALLBACK_BEHAVIOR(cc); |
| 615 ASSERT_EQ(PP_OK, cc.result()); | 617 ASSERT_EQ(PP_OK, cc.result()); |
| 618 ASSERT_EQ(cc.output().size, content_length); |
| 616 | 619 |
| 617 // Read the file and test that its contents match. | 620 // Read the file and test that its contents match. |
| 618 pp::FileIO file_io(instance_); | 621 pp::FileIO file_io(instance_); |
| 619 ASSERT_NE(0, file_io.pp_resource()); | 622 ASSERT_NE(0, file_io.pp_resource()); |
| 620 TestCompletionCallback callback(instance_->pp_instance(), | |
| 621 callback_type()); | |
| 622 callback.WaitForResult( | 623 callback.WaitForResult( |
| 623 file_io.Open(file_ref, PP_FILEOPENFLAG_READ, callback.GetCallback())); | 624 file_io.Open(file_ref, PP_FILEOPENFLAG_READ, callback.GetCallback())); |
| 624 CHECK_CALLBACK_BEHAVIOR(callback); | 625 CHECK_CALLBACK_BEHAVIOR(callback); |
| 625 ASSERT_EQ(PP_OK, callback.result()); | 626 ASSERT_EQ(PP_OK, callback.result()); |
| 626 | 627 |
| 627 int length = strlen(kTestString); | 628 std::vector<char> buffer_vector(content_length); |
| 628 std::vector<char> buffer_vector(length); | |
| 629 char* buffer = &buffer_vector[0]; // Note: Not null-terminated! | 629 char* buffer = &buffer_vector[0]; // Note: Not null-terminated! |
| 630 callback.WaitForResult( | 630 callback.WaitForResult( |
| 631 file_io.Read(0, buffer, length, callback.GetCallback())); | 631 file_io.Read(0, buffer, content_length, callback.GetCallback())); |
| 632 CHECK_CALLBACK_BEHAVIOR(callback); | 632 CHECK_CALLBACK_BEHAVIOR(callback); |
| 633 ASSERT_EQ(length, callback.result()); | 633 ASSERT_EQ(callback.result(), content_length); |
| 634 ASSERT_EQ(0, memcmp(buffer, kTestString, length)); | 634 ASSERT_EQ(0, memcmp(buffer, kTestString, content_length)); |
| 635 } | 635 } |
| 636 | 636 |
| 637 WaitForMessages(); | 637 WaitForMessages(); |
| 638 message_data_.clear(); | 638 message_data_.clear(); |
| 639 ASSERT_TRUE(ClearListeners()); | 639 ASSERT_TRUE(ClearListeners()); |
| 640 | 640 |
| 641 // TODO(mgiuca): Test roundtrip from plugin to JS and back, when the plugin to | |
| 642 // JS support is available. | |
| 643 | |
| 644 PASS(); | 641 PASS(); |
| 645 } | 642 } |
| 646 | 643 |
| 647 std::string TestPostMessage::TestSendingComplexVar() { | 644 std::string TestPostMessage::TestSendingComplexVar() { |
| 648 // Clean up after previous tests. This also swallows the message sent by Init | 645 // Clean up after previous tests. This also swallows the message sent by Init |
| 649 // if we didn't run the 'SendInInit' test. All tests other than 'SendInInit' | 646 // if we didn't run the 'SendInInit' test. All tests other than 'SendInInit' |
| 650 // should start with these. | 647 // should start with these. |
| 651 WaitForMessages(); | 648 WaitForMessages(); |
| 652 message_data_.clear(); | 649 message_data_.clear(); |
| 653 ASSERT_TRUE(ClearListeners()); | 650 ASSERT_TRUE(ClearListeners()); |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 867 ASSERT_TRUE(received_value <= kThreadsToRun); | 864 ASSERT_TRUE(received_value <= kThreadsToRun); |
| 868 ++received_counts[received_value]; | 865 ++received_counts[received_value]; |
| 869 } | 866 } |
| 870 ASSERT_EQ(expected_counts, received_counts); | 867 ASSERT_EQ(expected_counts, received_counts); |
| 871 | 868 |
| 872 message_data_.clear(); | 869 message_data_.clear(); |
| 873 ASSERT_TRUE(ClearListeners()); | 870 ASSERT_TRUE(ClearListeners()); |
| 874 | 871 |
| 875 PASS(); | 872 PASS(); |
| 876 } | 873 } |
| OLD | NEW |