diff options
25 files changed, 454 insertions, 230 deletions
diff --git a/chrome/renderer/pepper_plugin_delegate_impl.cc b/chrome/renderer/pepper_plugin_delegate_impl.cc index 9282e7b..06ca49a 100644 --- a/chrome/renderer/pepper_plugin_delegate_impl.cc +++ b/chrome/renderer/pepper_plugin_delegate_impl.cc @@ -739,6 +739,14 @@ bool PepperPluginDelegateImpl::Rename( return file_system_dispatcher->Move(file_path, new_file_path, dispatcher); } +bool PepperPluginDelegateImpl::ReadDirectory( + const FilePath& directory_path, + fileapi::FileSystemCallbackDispatcher* dispatcher) { + FileSystemDispatcher* file_system_dispatcher = + ChildThread::current()->file_system_dispatcher(); + return file_system_dispatcher->ReadDirectory(directory_path, dispatcher); +} + FilePath GetModuleLocalFilePath(const std::string& module_name, const FilePath& path) { #if defined(OS_WIN) diff --git a/chrome/renderer/pepper_plugin_delegate_impl.h b/chrome/renderer/pepper_plugin_delegate_impl.h index 90c659a..f817862 100644 --- a/chrome/renderer/pepper_plugin_delegate_impl.h +++ b/chrome/renderer/pepper_plugin_delegate_impl.h @@ -104,6 +104,8 @@ class PepperPluginDelegateImpl virtual bool Rename(const FilePath& file_path, const FilePath& new_file_path, fileapi::FileSystemCallbackDispatcher* dispatcher); + virtual bool ReadDirectory(const FilePath& directory_path, + fileapi::FileSystemCallbackDispatcher* dispatcher); virtual base::PlatformFileError OpenModuleLocalFile( const std::string& module_name, const FilePath& path, diff --git a/chrome/test/ui/ppapi_uitest.cc b/chrome/test/ui/ppapi_uitest.cc index 36eeab8..6fa1e2d 100644 --- a/chrome/test/ui/ppapi_uitest.cc +++ b/chrome/test/ui/ppapi_uitest.cc @@ -135,3 +135,15 @@ TEST_F(PPAPITest, CharSet) { TEST_F(PPAPITest, Var) { RunTest("Var"); } + +TEST_F(PPAPITest, FileRef) { + RunTestViaHTTP("FileRef"); +} + +TEST_F(PPAPITest, FileIO) { + RunTestViaHTTP("FileIO"); +} + +TEST_F(PPAPITest, DirectoryReader) { + RunTestViaHTTP("DirectoryReader"); +} diff --git a/ppapi/ppapi.gyp b/ppapi/ppapi.gyp index 2af075f..3a747d7 100644 --- a/ppapi/ppapi.gyp +++ b/ppapi/ppapi.gyp @@ -421,6 +421,8 @@ 'tests/test_buffer.h', 'tests/test_char_set.cc', 'tests/test_char_set.h', + 'tests/test_directory_reader.cc', + 'tests/test_directory_reader.h', 'tests/test_file_io.cc', 'tests/test_file_io.h', 'tests/test_file_ref.cc', @@ -439,6 +441,8 @@ 'tests/test_url_loader.h', 'tests/test_url_util.cc', 'tests/test_url_util.h', + 'tests/test_utils.cc', + 'tests/test_utils.h', 'tests/test_var.cc', 'tests/test_var.h', diff --git a/ppapi/tests/test_case.cc b/ppapi/tests/test_case.cc index a37bfc3..20a7f5f 100644 --- a/ppapi/tests/test_case.cc +++ b/ppapi/tests/test_case.cc @@ -6,6 +6,9 @@ #include <sstream> +#include "ppapi/tests/test_utils.h" +#include "ppapi/tests/testing_instance.h" + std::string TestCase::MakeFailureMessage(const char* file, int line, const char* cmd) { @@ -35,3 +38,27 @@ pp::deprecated::ScriptableObject* TestCase::CreateTestObject() { return NULL; } +bool TestCase::InitTestingInterface() { + if (!GetTestingInterface()) { + // Give a more helpful error message for the testing interface being gone + // since that needs special enabling in Chrome. + instance_->AppendError("This test needs the testing interface, which is " + "not currently available. In Chrome, use " + "--enable-pepper-testing when launching."); + return false; + } + + return true; +} + +bool TestCase::EnsureRunningOverHTTP() { + pp::Var window = instance_->GetWindowObject(); + pp::Var location = window.GetProperty("location"); + pp::Var protocol = location.GetProperty("protocol"); + if (!protocol.is_string() || protocol.AsString() != "http:") { + instance_->AppendError("This test needs to be run over HTTP."); + return false; + } + + return true; +} diff --git a/ppapi/tests/test_case.h b/ppapi/tests/test_case.h index 0ca6d8e..35026fe 100644 --- a/ppapi/tests/test_case.h +++ b/ppapi/tests/test_case.h @@ -47,6 +47,12 @@ class TestCase { // caller. Return NULL if there is no supported test object (the default). virtual pp::deprecated::ScriptableObject* CreateTestObject(); + // Initializes the testing interface. + bool InitTestingInterface(); + + // Makes sure the test is run over HTTP. + bool EnsureRunningOverHTTP(); + // Pointer to the instance that owns us. TestingInstance* instance_; diff --git a/ppapi/tests/test_directory_reader.cc b/ppapi/tests/test_directory_reader.cc new file mode 100644 index 0000000..d8bf737 --- /dev/null +++ b/ppapi/tests/test_directory_reader.cc @@ -0,0 +1,143 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ppapi/tests/test_directory_reader.h" + +#include <stdio.h> +#include <set> +#include <vector> + +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/dev/ppb_file_io_dev.h" +#include "ppapi/cpp/dev/directory_entry_dev.h" +#include "ppapi/cpp/dev/directory_reader_dev.h" +#include "ppapi/cpp/dev/file_io_dev.h" +#include "ppapi/cpp/dev/file_ref_dev.h" +#include "ppapi/cpp/dev/file_system_dev.h" +#include "ppapi/cpp/instance.h" +#include "ppapi/tests/test_utils.h" +#include "ppapi/tests/testing_instance.h" + +REGISTER_TEST_CASE(DirectoryReader); + +namespace { + +std::string IntegerToString(int value) { + char result[12]; + sprintf(result, "%d", value); + return result; +} + +} // namespace + +bool TestDirectoryReader::Init() { + return InitTestingInterface() && EnsureRunningOverHTTP(); +} + +void TestDirectoryReader::RunTest() { + RUN_TEST(GetNextFile); +} + +std::string TestDirectoryReader::TestGetNextFile() { + TestCompletionCallback callback; + pp::FileSystem_Dev file_system( + instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY); + int32_t rv = file_system.Open(1024, callback); + if (rv == PP_ERROR_WOULDBLOCK) + rv = callback.WaitForResult(); + if (rv != PP_OK) + return ReportError("FileSystem::Open", rv); + + pp::FileRef_Dev dir_ref(file_system, "/"); + pp::FileRef_Dev file_ref_1(file_system, "/file_1"); + pp::FileRef_Dev file_ref_2(file_system, "/file_2"); + pp::FileRef_Dev file_ref_3(file_system, "/file_3"); + + pp::FileIO_Dev file_io_1; + rv = file_io_1.Open(file_ref_1, PP_FILEOPENFLAG_CREATE, callback); + if (rv == PP_ERROR_WOULDBLOCK) + rv = callback.WaitForResult(); + if (rv != PP_OK) + return ReportError("FileIO::Open", rv); + pp::FileIO_Dev file_io_2; + rv = file_io_2.Open(file_ref_2, PP_FILEOPENFLAG_CREATE, callback); + if (rv == PP_ERROR_WOULDBLOCK) + rv = callback.WaitForResult(); + if (rv != PP_OK) + return ReportError("FileIO::Open", rv); + pp::FileIO_Dev file_io_3; + rv = file_io_3.Open(file_ref_3, PP_FILEOPENFLAG_CREATE, callback); + if (rv == PP_ERROR_WOULDBLOCK) + rv = callback.WaitForResult(); + if (rv != PP_OK) + return ReportError("FileIO::Open", rv); + + pp::FileRef_Dev dir_ref_1(file_system, "/dir_1"); + pp::FileRef_Dev dir_ref_2(file_system, "/dir_2"); + pp::FileRef_Dev dir_ref_3(file_system, "/dir_3"); + rv = dir_ref_1.MakeDirectory(callback); + if (rv == PP_ERROR_WOULDBLOCK) + rv = callback.WaitForResult(); + if (rv != PP_OK) + return ReportError("FileRef::MakeDirectory", rv); + rv = dir_ref_2.MakeDirectory(callback); + if (rv == PP_ERROR_WOULDBLOCK) + rv = callback.WaitForResult(); + if (rv != PP_OK) + return ReportError("FileRef::MakeDirectory", rv); + rv = dir_ref_3.MakeDirectory(callback); + if (rv == PP_ERROR_WOULDBLOCK) + rv = callback.WaitForResult(); + if (rv != PP_OK) + return ReportError("FileRef::MakeDirectory", rv); + + pp::DirectoryReader_Dev directory_reader(dir_ref); + std::vector<pp::DirectoryEntry_Dev> entries; + pp::DirectoryEntry_Dev entry; + do { + rv = directory_reader.GetNextEntry(&entry, callback); + if (rv == PP_ERROR_WOULDBLOCK) + rv = callback.WaitForResult(); + if (rv != PP_OK) + return ReportError("DirectoryReader::GetNextEntry", rv); + if (!entry.is_null()) + entries.push_back(entry); + } while (!entry.is_null()); + + if (entries.size() != 6) + return "Expected 6 entries, got " + IntegerToString(entries.size()); + + std::set<std::string> expected_file_names; + expected_file_names.insert("/file_1"); + expected_file_names.insert("/file_2"); + expected_file_names.insert("/file_3"); + + std::set<std::string> expected_dir_names; + expected_dir_names.insert("/dir_1"); + expected_dir_names.insert("/dir_2"); + expected_dir_names.insert("/dir_3"); + + for (std::vector<pp::DirectoryEntry_Dev>::const_iterator it = entries.begin(); + it != entries.end(); it++) { + pp::FileRef_Dev file_ref = it->file_ref(); + std::string file_path = file_ref.GetPath().AsString(); + std::set<std::string>::iterator found = expected_file_names.find(file_path); + if (found != expected_file_names.end()) { + if (it->file_type() != PP_FILETYPE_REGULAR) + return file_path + " should have been a regular file."; + expected_file_names.erase(found); + } else { + found = expected_dir_names.find(file_path); + if (found == expected_dir_names.end()) + return "Unexpected file path: " + file_path; + if (it->file_type() != PP_FILETYPE_DIRECTORY) + return file_path + " should have been a directory."; + expected_dir_names.erase(found); + } + } + if (!expected_file_names.empty() || !expected_dir_names.empty()) + return "Expected more file paths."; + + return ""; +} diff --git a/ppapi/tests/test_directory_reader.h b/ppapi/tests/test_directory_reader.h new file mode 100644 index 0000000..932d1b3 --- /dev/null +++ b/ppapi/tests/test_directory_reader.h @@ -0,0 +1,25 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PAPPI_TESTS_TEST_DIRECTORY_READER_H_ +#define PAPPI_TESTS_TEST_DIRECTORY_READER_H_ + +#include <string> + +#include "ppapi/tests/test_case.h" + +class TestDirectoryReader : public TestCase { + public: + explicit TestDirectoryReader(TestingInstance* instance) + : TestCase(instance) {} + + // TestCase implementation. + virtual bool Init(); + virtual void RunTest(); + + private: + std::string TestGetNextFile(); +}; + +#endif // PAPPI_TESTS_TEST_DIRECTORY_READER_H_ diff --git a/ppapi/tests/test_file_io.cc b/ppapi/tests/test_file_io.cc index 300052d..5ba571a 100644 --- a/ppapi/tests/test_file_io.cc +++ b/ppapi/tests/test_file_io.cc @@ -14,49 +14,13 @@ #include "ppapi/cpp/dev/file_system_dev.h" #include "ppapi/cpp/instance.h" #include "ppapi/cpp/module.h" +#include "ppapi/tests/test_utils.h" #include "ppapi/tests/testing_instance.h" REGISTER_TEST_CASE(FileIO); namespace { -const PPB_Testing_Dev* g_testing_interface; - -class TestCompletionCallback { - public: - TestCompletionCallback() : result_(PP_ERROR_WOULDBLOCK) { - } - - operator pp::CompletionCallback() const { - return pp::CompletionCallback(&TestCompletionCallback::Handler, - const_cast<TestCompletionCallback*>(this)); - } - - int32_t WaitForResult() { - result_ = PP_ERROR_WOULDBLOCK; // Reset - g_testing_interface->RunMessageLoop(); - return result_; - } - - private: - static void Handler(void* user_data, int32_t result) { - static_cast<TestCompletionCallback*>(user_data)->result_ = result; - g_testing_interface->QuitMessageLoop(); - } - - int32_t result_; -}; - -std::string ReportError(const char* method, int32_t error) { - char error_as_string[12]; - sprintf(error_as_string, "%d", error); - std::string result = method + std::string(" failed with error: ") + - error_as_string; - if (error == PP_ERROR_NOSPACE) - result += ". Did you run the test with --unlimited-quota-for-files?"; - return result; -} - std::string ReportMismatch(const std::string& method_name, const std::string& returned_result, const std::string& expected_result) { @@ -112,27 +76,7 @@ int32_t WriteEntireBuffer(pp::FileIO_Dev* file_io, } // namespace bool TestFileIO::Init() { - g_testing_interface = reinterpret_cast<PPB_Testing_Dev const*>( - pp::Module::Get()->GetBrowserInterface(PPB_TESTING_DEV_INTERFACE)); - if (!g_testing_interface) { - // Give a more helpful error message for the testing interface being gone - // since that needs special enabling in Chrome. - instance_->AppendError("This test needs the testing interface, which is " - "not currently available. In Chrome, use --enable-pepper-testing when " - "launching."); - return false; - } - - // Make sure we're running over HTTP. - pp::Var window = instance_->GetWindowObject(); - pp::Var location = window.GetProperty("location"); - pp::Var protocol = location.GetProperty("protocol"); - if (!protocol.is_string() || protocol.AsString() != "http:") { - instance_->AppendError("This test needs to be run over HTTP."); - return false; - } - - return true; + return InitTestingInterface() && EnsureRunningOverHTTP(); } void TestFileIO::RunTest() { diff --git a/ppapi/tests/test_file_ref.cc b/ppapi/tests/test_file_ref.cc index b83a2f4..513f5dd 100644 --- a/ppapi/tests/test_file_ref.cc +++ b/ppapi/tests/test_file_ref.cc @@ -17,6 +17,7 @@ #include "ppapi/cpp/dev/url_response_info_dev.h" #include "ppapi/cpp/instance.h" #include "ppapi/cpp/module.h" +#include "ppapi/tests/test_utils.h" #include "ppapi/tests/testing_instance.h" REGISTER_TEST_CASE(FileRef); @@ -29,33 +30,6 @@ const char* kParentPath = "/foo/bar"; const char* kPersFilePath = "/foo/bar/persistent"; const char* kTempFilePath = "/foo/bar/temporary"; -const PPB_Testing_Dev* g_testing_interface; - -class TestCompletionCallback { - public: - TestCompletionCallback() : result_(PP_ERROR_WOULDBLOCK) { - } - - operator pp::CompletionCallback() const { - return pp::CompletionCallback(&TestCompletionCallback::Handler, - const_cast<TestCompletionCallback*>(this)); - } - - int32_t WaitForResult() { - result_ = PP_ERROR_WOULDBLOCK; // Reset - g_testing_interface->RunMessageLoop(); - return result_; - } - - private: - static void Handler(void* user_data, int32_t result) { - static_cast<TestCompletionCallback*>(user_data)->result_ = result; - g_testing_interface->QuitMessageLoop(); - } - - int32_t result_; -}; - std::string ReportMismatch(const std::string& method_name, const std::string& returned_result, const std::string& expected_result) { @@ -63,40 +37,10 @@ std::string ReportMismatch(const std::string& method_name, expected_result + "' expected."; } -std::string ReportError(const char* method, int32_t error) { - char error_as_string[12]; - sprintf(error_as_string, "%d", error); - std::string result = method + std::string(" failed with error: ") + - error_as_string; - if (error == PP_ERROR_NOSPACE) - result += ". Did you run the test with --unlimited-quota-for-files?"; - return result; -} - } // namespace bool TestFileRef::Init() { - g_testing_interface = reinterpret_cast<PPB_Testing_Dev const*>( - pp::Module::Get()->GetBrowserInterface(PPB_TESTING_DEV_INTERFACE)); - if (!g_testing_interface) { - // Give a more helpful error message for the testing interface being gone - // since that needs special enabling in Chrome. - instance_->AppendError("This test needs the testing interface, which is " - "not currently available. In Chrome, use --enable-pepper-testing when " - "launching."); - return false; - } - - // Make sure we're running over HTTP. - pp::Var window = instance_->GetWindowObject(); - pp::Var location = window.GetProperty("location"); - pp::Var protocol = location.GetProperty("protocol"); - if (!protocol.is_string() || protocol.AsString() != "http:") { - instance_->AppendError("This test needs to be run over HTTP."); - return false; - } - - return true; + return InitTestingInterface() && EnsureRunningOverHTTP(); } void TestFileRef::RunTest() { diff --git a/ppapi/tests/test_transport.cc b/ppapi/tests/test_transport.cc index 9f506f6..2f3c09f 100644 --- a/ppapi/tests/test_transport.cc +++ b/ppapi/tests/test_transport.cc @@ -14,6 +14,7 @@ #include "ppapi/cpp/completion_callback.h" #include "ppapi/cpp/instance.h" #include "ppapi/cpp/module.h" +#include "ppapi/tests/test_utils.h" #include "ppapi/tests/testing_instance.h" REGISTER_TEST_CASE(Transport); @@ -21,17 +22,7 @@ REGISTER_TEST_CASE(Transport); bool TestTransport::Init() { transport_interface_ = reinterpret_cast<PPB_Transport_Dev const*>( pp::Module::Get()->GetBrowserInterface(PPB_TRANSPORT_DEV_INTERFACE)); - testing_interface_ = reinterpret_cast<PPB_Testing_Dev const*>( - pp::Module::Get()->GetBrowserInterface(PPB_TESTING_DEV_INTERFACE)); - if (!testing_interface_) { - // Give a more helpful error message for the testing interface being gone - // since that needs special enabling in Chrome. - instance_->AppendError("This test needs the testing interface, which is " - "not currently available. In Chrome, use --enable-pepper-testing when " - "launching."); - } - - return transport_interface_ && testing_interface_; + return transport_interface_ && InitTestingInterface(); } void TestTransport::RunTest() { @@ -39,12 +30,7 @@ void TestTransport::RunTest() { // TODO(juberti): more Transport tests here... } -void TestTransport::QuitMessageLoop() { - testing_interface_->QuitMessageLoop(); -} - std::string TestTransport::TestFirstTransport() { // TODO(juberti): actual test return ""; } - diff --git a/ppapi/tests/test_transport.h b/ppapi/tests/test_transport.h index f7b57be..e52983a 100644 --- a/ppapi/tests/test_transport.h +++ b/ppapi/tests/test_transport.h @@ -7,10 +7,8 @@ #include <string> -#include "ppapi/c/pp_stdint.h" #include "ppapi/tests/test_case.h" -struct PPB_Testing_Dev; struct PPB_Transport_Dev; namespace pp { @@ -25,15 +23,11 @@ class TestTransport : public TestCase { virtual bool Init(); virtual void RunTest(); - void QuitMessageLoop(); - private: std::string TestFirstTransport(); // Used by the tests that access the C API directly. - const PPB_Testing_Dev* testing_interface_; const PPB_Transport_Dev* transport_interface_; }; #endif // PAPPI_TESTS_TEST_TRANSPORT_H_ - diff --git a/ppapi/tests/test_url_loader.cc b/ppapi/tests/test_url_loader.cc index 9fb64f2..b1cdd6f 100644 --- a/ppapi/tests/test_url_loader.cc +++ b/ppapi/tests/test_url_loader.cc @@ -5,13 +5,12 @@ #include "ppapi/tests/test_url_loader.h" #include <stdio.h> -#include <string.h> +#include <string> #include "ppapi/c/dev/ppb_file_io_dev.h" #include "ppapi/c/dev/ppb_testing_dev.h" #include "ppapi/c/dev/ppb_url_loader_dev.h" #include "ppapi/c/pp_errors.h" -#include "ppapi/cpp/completion_callback.h" #include "ppapi/cpp/dev/file_io_dev.h" #include "ppapi/cpp/dev/file_ref_dev.h" #include "ppapi/cpp/dev/file_system_dev.h" @@ -20,69 +19,13 @@ #include "ppapi/cpp/dev/url_response_info_dev.h" #include "ppapi/cpp/instance.h" #include "ppapi/cpp/module.h" +#include "ppapi/tests/test_utils.h" #include "ppapi/tests/testing_instance.h" REGISTER_TEST_CASE(URLLoader); -namespace { - -const PPB_Testing_Dev* g_testing_interface; - -class TestCompletionCallback { - public: - TestCompletionCallback() : result_(PP_ERROR_WOULDBLOCK) { - } - - operator pp::CompletionCallback() const { - return pp::CompletionCallback(&TestCompletionCallback::Handler, - const_cast<TestCompletionCallback*>(this)); - } - - int32_t WaitForResult() { - result_ = PP_ERROR_WOULDBLOCK; // Reset - g_testing_interface->RunMessageLoop(); - return result_; - } - - private: - static void Handler(void* user_data, int32_t result) { - static_cast<TestCompletionCallback*>(user_data)->result_ = result; - g_testing_interface->QuitMessageLoop(); - } - - int32_t result_; -}; - -std::string ReportError(const char* method, int32_t error) { - char error_as_string[12]; - sprintf(error_as_string, "%d", error); - return method + std::string(" failed with error: ") + error_as_string; -} - -} // namespace - bool TestURLLoader::Init() { - g_testing_interface = reinterpret_cast<PPB_Testing_Dev const*>( - pp::Module::Get()->GetBrowserInterface(PPB_TESTING_DEV_INTERFACE)); - if (!g_testing_interface) { - // Give a more helpful error message for the testing interface being gone - // since that needs special enabling in Chrome. - instance_->AppendError("This test needs the testing interface, which is " - "not currently available. In Chrome, use --enable-pepper-testing when " - "launching."); - return false; - } - - // Make sure we're running over HTTP. - pp::Var window = instance_->GetWindowObject(); - pp::Var location = window.GetProperty("location"); - pp::Var protocol = location.GetProperty("protocol"); - if (!protocol.is_string() || protocol.AsString() != "http:") { - instance_->AppendError("This test needs to be run over HTTP."); - return false; - } - - return true; + return InitTestingInterface() && EnsureRunningOverHTTP(); } void TestURLLoader::RunTest() { diff --git a/ppapi/tests/test_url_util.cc b/ppapi/tests/test_url_util.cc index a5749d7..ea91506 100644 --- a/ppapi/tests/test_url_util.cc +++ b/ppapi/tests/test_url_util.cc @@ -115,4 +115,3 @@ std::string TestUrlUtil::TestDocumentCanAccessDocument() { ASSERT_TRUE(util_->DocumentCanAccessDocument(*instance_, *instance_)); return std::string(); } - diff --git a/ppapi/tests/test_utils.cc b/ppapi/tests/test_utils.cc new file mode 100644 index 0000000..a062922 --- /dev/null +++ b/ppapi/tests/test_utils.cc @@ -0,0 +1,53 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ppapi/tests/test_utils.h" + +#include "ppapi/c/pp_errors.h" +#include "ppapi/cpp/module.h" + +const PPB_Testing_Dev* GetTestingInterface() { + static const PPB_Testing_Dev* g_testing_interface = + reinterpret_cast<PPB_Testing_Dev const*>( + pp::Module::Get()->GetBrowserInterface(PPB_TESTING_DEV_INTERFACE)); + return g_testing_interface; +} + +std::string ReportError(const char* method, int32_t error) { + char error_as_string[12]; + sprintf(error_as_string, "%d", error); + std::string result = method + std::string(" failed with error: ") + + error_as_string; + if (error == PP_ERROR_NOSPACE) + result += ". Did you run the test with --unlimited-quota-for-files?"; + return result; +} + +TestCompletionCallback::TestCompletionCallback() + : result_(PP_ERROR_WOULDBLOCK), + post_quit_task_(false) { +} + +int32_t TestCompletionCallback::WaitForResult() { + result_ = PP_ERROR_WOULDBLOCK; // Reset + post_quit_task_ = true; + GetTestingInterface()->RunMessageLoop(); + return result_; +} + +TestCompletionCallback::operator pp::CompletionCallback() const { + return pp::CompletionCallback(&TestCompletionCallback::Handler, + const_cast<TestCompletionCallback*>(this)); +} + +// static +void TestCompletionCallback::Handler(void* user_data, int32_t result) { + TestCompletionCallback* callback = + static_cast<TestCompletionCallback*>(user_data); + callback->result_ = result; + if (callback->post_quit_task_) { + callback->post_quit_task_ = false; + GetTestingInterface()->QuitMessageLoop(); + } +} diff --git a/ppapi/tests/test_utils.h b/ppapi/tests/test_utils.h new file mode 100644 index 0000000..7af515d --- /dev/null +++ b/ppapi/tests/test_utils.h @@ -0,0 +1,32 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PPAPI_TESTS_TEST_UTILS_H_ +#define PPAPI_TESTS_TEST_UTILS_H_ + +#include <string> + +#include "ppapi/c/dev/ppb_testing_dev.h" +#include "ppapi/c/pp_stdint.h" +#include "ppapi/cpp/completion_callback.h" + +const PPB_Testing_Dev* GetTestingInterface(); +std::string ReportError(const char* method, int32_t error); + +class TestCompletionCallback { + public: + TestCompletionCallback(); + + int32_t WaitForResult(); + + operator pp::CompletionCallback() const; + + private: + static void Handler(void* user_data, int32_t result); + + int32_t result_; + bool post_quit_task_; +}; + +#endif // PPAPI_TESTS_TEST_UTILS_H_ diff --git a/ppapi/tests/test_var.cc b/ppapi/tests/test_var.cc index efd0dd1..c9a1339 100644 --- a/ppapi/tests/test_var.cc +++ b/ppapi/tests/test_var.cc @@ -7,10 +7,10 @@ #include <limits> #include "ppapi/c/pp_var.h" -#include "ppapi/c/dev/ppb_testing_dev.h" #include "ppapi/c/ppb_var.h" #include "ppapi/cpp/module.h" #include "ppapi/cpp/var.h" +#include "ppapi/tests/test_utils.h" #include "ppapi/tests/testing_instance.h" REGISTER_TEST_CASE(Var); @@ -24,16 +24,7 @@ pp::Var adoptVar(PP_Var var) { bool TestVar::Init() { var_interface_ = reinterpret_cast<PPB_Var const*>( pp::Module::Get()->GetBrowserInterface(PPB_VAR_INTERFACE)); - testing_interface_ = reinterpret_cast<PPB_Testing_Dev const*>( - pp::Module::Get()->GetBrowserInterface(PPB_TESTING_DEV_INTERFACE)); - if (!testing_interface_) { - // Give a more helpful error message for the testing interface being gone - // since that needs special enabling in Chrome. - instance_->AppendError("This test needs the testing interface, which is " - "not currently available. In Chrome, use --enable-pepper-testing when " - "launching."); - } - return var_interface_ && testing_interface_; + return var_interface_ && InitTestingInterface(); } void TestVar::RunTest() { @@ -175,4 +166,3 @@ std::string TestVar::TestDefineProperty() { PASS(); } - diff --git a/ppapi/tests/test_var.h b/ppapi/tests/test_var.h index 8499003..3a0229b 100644 --- a/ppapi/tests/test_var.h +++ b/ppapi/tests/test_var.h @@ -9,7 +9,6 @@ #include "ppapi/tests/test_case.h" -struct PPB_Testing_Dev; struct PPB_Var; class TestVar : public TestCase { @@ -26,7 +25,6 @@ class TestVar : public TestCase { // Used by the tests that access the C API directly. const PPB_Var* var_interface_; - const PPB_Testing_Dev* testing_interface_; }; #endif // PPAPI_TEST_TEST_VAR_H_ diff --git a/webkit/glue/plugins/pepper_directory_reader.cc b/webkit/glue/plugins/pepper_directory_reader.cc index a40ef1d..558560e 100644 --- a/webkit/glue/plugins/pepper_directory_reader.cc +++ b/webkit/glue/plugins/pepper_directory_reader.cc @@ -5,16 +5,42 @@ #include "webkit/glue/plugins/pepper_directory_reader.h" #include "base/logging.h" +#include "base/utf_string_conversions.h" #include "ppapi/c/pp_completion_callback.h" -#include "ppapi/c/dev/ppb_directory_reader_dev.h" #include "ppapi/c/pp_errors.h" +#include "ppapi/c/dev/ppb_directory_reader_dev.h" +#include "webkit/glue/plugins/pepper_file_callbacks.h" #include "webkit/glue/plugins/pepper_file_ref.h" +#include "webkit/glue/plugins/pepper_file_system.h" +#include "webkit/glue/plugins/pepper_plugin_delegate.h" +#include "webkit/glue/plugins/pepper_plugin_instance.h" +#include "webkit/glue/plugins/pepper_plugin_module.h" #include "webkit/glue/plugins/pepper_resource_tracker.h" namespace pepper { namespace { +std::string FilePathStringToUTF8String(const FilePath::StringType& str) { +#if defined(OS_WIN) + return WideToUTF8(str); +#elif defined(OS_POSIX) + return str; +#else +#error "Unsupported platform." +#endif +} + +FilePath::StringType UTF8StringToFilePathString(const std::string& str) { +#if defined(OS_WIN) + return UTF8ToWide(str); +#elif defined(OS_POSIX) + return str; +#else +#error "Unsupported platform." +#endif +} + PP_Resource Create(PP_Resource directory_ref_id) { scoped_refptr<FileRef> directory_ref( Resource::GetAs<FileRef>(directory_ref_id)); @@ -50,7 +76,9 @@ const PPB_DirectoryReader_Dev ppb_directoryreader = { DirectoryReader::DirectoryReader(FileRef* directory_ref) : Resource(directory_ref->module()), - directory_ref_(directory_ref) { + directory_ref_(directory_ref), + has_more_(true), + entry_(NULL) { } DirectoryReader::~DirectoryReader() { @@ -62,8 +90,66 @@ const PPB_DirectoryReader_Dev* DirectoryReader::GetInterface() { int32_t DirectoryReader::GetNextEntry(PP_DirectoryEntry_Dev* entry, PP_CompletionCallback callback) { - NOTIMPLEMENTED(); // TODO(darin): Implement me! - return PP_ERROR_FAILED; + if (directory_ref_->GetFileSystemType() == PP_FILESYSTEMTYPE_EXTERNAL) + return PP_ERROR_FAILED; + + entry_ = entry; + if (FillUpEntry()) { + entry_ = NULL; + return PP_OK; + } + + PluginInstance* instance = directory_ref_->GetFileSystem()->instance(); + if (!instance->delegate()->ReadDirectory( + directory_ref_->GetSystemPath(), + new FileCallbacks(instance->module()->AsWeakPtr(), + callback, NULL, NULL, this))) + return PP_ERROR_FAILED; + + return PP_ERROR_WOULDBLOCK; +} + +void DirectoryReader::AddNewEntries( + const std::vector<base::FileUtilProxy::Entry>& entries, bool has_more) { + DCHECK(!entries.empty()); + has_more_ = has_more; + std::string dir_path = directory_ref_->GetPath(); + if (dir_path[dir_path.size() - 1] != '/') + dir_path += '/'; + FilePath::StringType dir_file_path = UTF8StringToFilePathString(dir_path); + for (std::vector<base::FileUtilProxy::Entry>::const_iterator it = + entries.begin(); it != entries.end(); it++) { + base::FileUtilProxy::Entry entry; + entry.name = dir_file_path + it->name; + entry.is_directory = it->is_directory; + entries_.push(entry); + } + + FillUpEntry(); + entry_ = NULL; +} + +bool DirectoryReader::FillUpEntry() { + DCHECK(entry_); + if (!entries_.empty()) { + base::FileUtilProxy::Entry dir_entry = entries_.front(); + entries_.pop(); + if (entry_->file_ref) + ResourceTracker::Get()->UnrefResource(entry_->file_ref); + FileRef* file_ref = new FileRef(module(), directory_ref_->GetFileSystem(), + FilePathStringToUTF8String(dir_entry.name)); + entry_->file_ref = file_ref->GetReference(); + entry_->file_type = + (dir_entry.is_directory ? PP_FILETYPE_DIRECTORY : PP_FILETYPE_REGULAR); + return true; + } + + if (!has_more_) { + entry_->file_ref = 0; + return true; + } + + return false; } } // namespace pepper diff --git a/webkit/glue/plugins/pepper_directory_reader.h b/webkit/glue/plugins/pepper_directory_reader.h index a56d546..38496bb8 100644 --- a/webkit/glue/plugins/pepper_directory_reader.h +++ b/webkit/glue/plugins/pepper_directory_reader.h @@ -5,6 +5,9 @@ #ifndef WEBKIT_GLUE_PLUGINS_PEPPER_DIRECTORY_READER_H_ #define WEBKIT_GLUE_PLUGINS_PEPPER_DIRECTORY_READER_H_ +#include <queue> + +#include "base/file_util_proxy.h" #include "webkit/glue/plugins/pepper_resource.h" struct PP_CompletionCallback; @@ -31,8 +34,16 @@ class DirectoryReader : public Resource { int32_t GetNextEntry(PP_DirectoryEntry_Dev* entry, PP_CompletionCallback callback); + void AddNewEntries(const std::vector<base::FileUtilProxy::Entry>& entries, + bool has_more); + private: + bool FillUpEntry(); + scoped_refptr<FileRef> directory_ref_; + std::queue<base::FileUtilProxy::Entry> entries_; + bool has_more_; + PP_DirectoryEntry_Dev* entry_; }; } // namespace pepper diff --git a/webkit/glue/plugins/pepper_file_callbacks.cc b/webkit/glue/plugins/pepper_file_callbacks.cc index fe6ad95..e24927a 100644 --- a/webkit/glue/plugins/pepper_file_callbacks.cc +++ b/webkit/glue/plugins/pepper_file_callbacks.cc @@ -9,6 +9,7 @@ #include "ppapi/c/dev/ppb_file_system_dev.h" #include "ppapi/c/dev/pp_file_info_dev.h" #include "ppapi/c/pp_errors.h" +#include "webkit/glue/plugins/pepper_directory_reader.h" #include "webkit/glue/plugins/pepper_error_util.h" #include "webkit/glue/plugins/pepper_file_system.h" #include "webkit/fileapi/file_system_types.h" @@ -18,11 +19,13 @@ namespace pepper { FileCallbacks::FileCallbacks(const base::WeakPtr<PluginModule>& module, PP_CompletionCallback callback, PP_FileInfo_Dev* info, - scoped_refptr<FileSystem> file_system) + scoped_refptr<FileSystem> file_system, + scoped_refptr<DirectoryReader> directory_reader) : module_(module), callback_(callback), info_(info), - file_system_(file_system) { + file_system_(file_system), + directory_reader_(directory_reader) { } FileCallbacks::~FileCallbacks() {} @@ -55,8 +58,14 @@ void FileCallbacks::DidReadMetadata( } void FileCallbacks::DidReadDirectory( - const std::vector<base::FileUtilProxy::Entry>&, bool) { - NOTREACHED(); + const std::vector<base::FileUtilProxy::Entry>& entries, bool has_more) { + if (!module_.get() || !callback_.func) + return; + + DCHECK(directory_reader_); + directory_reader_->AddNewEntries(entries, has_more); + + PP_RunCompletionCallback(&callback_, PP_OK); } void FileCallbacks::DidOpenFileSystem(const std::string&, diff --git a/webkit/glue/plugins/pepper_file_callbacks.h b/webkit/glue/plugins/pepper_file_callbacks.h index 20cb8d3..d4a92f2c 100644 --- a/webkit/glue/plugins/pepper_file_callbacks.h +++ b/webkit/glue/plugins/pepper_file_callbacks.h @@ -18,6 +18,7 @@ class FilePath; namespace pepper { +class DirectoryReader; class FileSystem; class PluginModule; @@ -27,14 +28,15 @@ class FileCallbacks : public fileapi::FileSystemCallbackDispatcher { FileCallbacks(const base::WeakPtr<PluginModule>& module, PP_CompletionCallback callback, PP_FileInfo_Dev* info, - scoped_refptr<FileSystem> file_system); + scoped_refptr<FileSystem> file_system, + scoped_refptr<DirectoryReader> directory_reader); virtual ~FileCallbacks(); // FileSystemCallbackDispatcher implementation. virtual void DidSucceed(); virtual void DidReadMetadata(const base::PlatformFileInfo& file_info); virtual void DidReadDirectory( - const std::vector<base::FileUtilProxy::Entry>&, bool); + const std::vector<base::FileUtilProxy::Entry>& entries, bool has_more); virtual void DidOpenFileSystem(const std::string&, const FilePath& root_path); virtual void DidFail(base::PlatformFileError error_code); @@ -43,10 +45,11 @@ class FileCallbacks : public fileapi::FileSystemCallbackDispatcher { private: void RunCallback(base::PlatformFileError error_code); - base::WeakPtr<pepper::PluginModule> module_; + base::WeakPtr<PluginModule> module_; PP_CompletionCallback callback_; PP_FileInfo_Dev* info_; scoped_refptr<FileSystem> file_system_; + scoped_refptr<DirectoryReader> directory_reader_; }; } // namespace pepper diff --git a/webkit/glue/plugins/pepper_file_ref.cc b/webkit/glue/plugins/pepper_file_ref.cc index 8fb685b..a135cf6 100644 --- a/webkit/glue/plugins/pepper_file_ref.cc +++ b/webkit/glue/plugins/pepper_file_ref.cc @@ -7,6 +7,7 @@ #include "base/string_util.h" #include "base/utf_string_conversions.h" #include "ppapi/c/pp_errors.h" +#include "webkit/glue/plugins/pepper_directory_reader.h" #include "webkit/glue/plugins/pepper_file_callbacks.h" #include "webkit/glue/plugins/pepper_file_system.h" #include "webkit/glue/plugins/pepper_plugin_delegate.h" @@ -118,7 +119,7 @@ int32_t MakeDirectory(PP_Resource directory_ref_id, if (!instance->delegate()->MakeDirectory( directory_ref->GetSystemPath(), make_ancestors, new FileCallbacks(instance->module()->AsWeakPtr(), - callback, NULL, NULL))) + callback, NULL, NULL, NULL))) return PP_ERROR_FAILED; return PP_ERROR_WOULDBLOCK; @@ -140,7 +141,7 @@ int32_t Query(PP_Resource file_ref_id, if (!instance->delegate()->Query( file_ref->GetSystemPath(), new FileCallbacks(instance->module()->AsWeakPtr(), - callback, info, file_system))) + callback, info, file_system, NULL))) return PP_ERROR_FAILED; return PP_ERROR_WOULDBLOCK; @@ -164,7 +165,7 @@ int32_t Touch(PP_Resource file_ref_id, file_ref->GetSystemPath(), base::Time::FromDoubleT(last_access_time), base::Time::FromDoubleT(last_modified_time), new FileCallbacks(instance->module()->AsWeakPtr(), - callback, NULL, NULL))) + callback, NULL, NULL, NULL))) return PP_ERROR_FAILED; return PP_ERROR_WOULDBLOCK; @@ -185,7 +186,7 @@ int32_t Delete(PP_Resource file_ref_id, if (!instance->delegate()->Delete( file_ref->GetSystemPath(), new FileCallbacks(instance->module()->AsWeakPtr(), - callback, NULL, NULL))) + callback, NULL, NULL, NULL))) return PP_ERROR_FAILED; return PP_ERROR_WOULDBLOCK; @@ -213,7 +214,7 @@ int32_t Rename(PP_Resource file_ref_id, if (!instance->delegate()->Rename( file_ref->GetSystemPath(), new_file_ref->GetSystemPath(), new FileCallbacks(instance->module()->AsWeakPtr(), - callback, NULL, NULL))) + callback, NULL, NULL, NULL))) return PP_ERROR_FAILED; return PP_ERROR_WOULDBLOCK; diff --git a/webkit/glue/plugins/pepper_file_system.cc b/webkit/glue/plugins/pepper_file_system.cc index b2e17d5..9262798 100644 --- a/webkit/glue/plugins/pepper_file_system.cc +++ b/webkit/glue/plugins/pepper_file_system.cc @@ -12,6 +12,7 @@ #include "third_party/WebKit/WebKit/chromium/public/WebFrame.h" #include "third_party/WebKit/WebKit/chromium/public/WebPluginContainer.h" #include "webkit/fileapi/file_system_types.h" +#include "webkit/glue/plugins/pepper_directory_reader.h" #include "webkit/glue/plugins/pepper_file_callbacks.h" #include "webkit/glue/plugins/pepper_plugin_delegate.h" #include "webkit/glue/plugins/pepper_plugin_instance.h" @@ -57,7 +58,7 @@ int32_t Open(PP_Resource file_system_id, instance->container()->element().document().frame()->url(), file_system_type, expected_size, new FileCallbacks(instance->module()->AsWeakPtr(), - callback, NULL, file_system))) + callback, NULL, file_system, NULL))) return PP_ERROR_FAILED; return PP_ERROR_WOULDBLOCK; diff --git a/webkit/glue/plugins/pepper_plugin_delegate.h b/webkit/glue/plugins/pepper_plugin_delegate.h index 897b16f..0998355 100644 --- a/webkit/glue/plugins/pepper_plugin_delegate.h +++ b/webkit/glue/plugins/pepper_plugin_delegate.h @@ -198,6 +198,9 @@ class PluginDelegate { virtual bool Rename(const FilePath& file_path, const FilePath& new_file_path, fileapi::FileSystemCallbackDispatcher* dispatcher) = 0; + virtual bool ReadDirectory( + const FilePath& directory_path, + fileapi::FileSystemCallbackDispatcher* dispatcher) = 0; virtual base::PlatformFileError OpenModuleLocalFile( const std::string& module_name, |
