diff options
Diffstat (limited to 'chrome')
63 files changed, 1070 insertions, 262 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 9f159bb..0be26f8 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -4383,6 +4383,9 @@ Update checks have repeatedly failed for the extension "<ph name="EXTENSION_NAME <message name="IDS_EXTENSION_PROMPT_WARNING_DOWNLOADS" desc="Permission string for access to downloads."> Download files </message> + <message name="IDS_EXTENSION_PROMPT_WARNING_FILE_SYSTEM_WRITE" desc="Permission string for write access to the file system."> + Write to files that you have opened in the application + </message> <!-- Extension/App error messages --> <message name="IDS_EXTENSION_CANT_GET_ABSOLUTE_PATH" desc="Warning displayed in pack dialog when the absolute path to the extension directory can not be found."> diff --git a/chrome/browser/extensions/api/file_system/file_system_api.cc b/chrome/browser/extensions/api/file_system/file_system_api.cc index d70eea3..dc0742a 100644 --- a/chrome/browser/extensions/api/file_system/file_system_api.cc +++ b/chrome/browser/extensions/api/file_system/file_system_api.cc @@ -10,8 +10,8 @@ #include "chrome/browser/extensions/shell_window_registry.h" #include "chrome/browser/platform_util.h" #include "chrome/browser/ui/extensions/shell_window.h" -#include "chrome/browser/ui/select_file_dialog.h" #include "chrome/common/extensions/api/file_system.h" +#include "chrome/common/extensions/permissions/api_permission.h" #include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_process_host.h" @@ -24,7 +24,12 @@ const char kSecurityError[] = "Security error"; const char kInvalidCallingPage[] = "Invalid calling page"; const char kUserCancelled[] = "User cancelled"; const char kWritableFileError[] = "Invalid file for writing"; +const char kRequiresFileSystemWriteError[] = + "Operation requires fileSystemWrite permission"; +const char kUnknownChooseFileType[] = "Unknown type"; +const char kOpenFileOption[] = "openFile"; +const char kOpenWritableFileOption[] ="openWritableFile"; const char kSaveFileOption[] = "saveFile"; namespace file_system = extensions::api::file_system; @@ -98,24 +103,107 @@ bool FileSystemGetDisplayPathFunction::RunImpl() { FilePath file_path; if (!GetFilePathOfFileEntry(filesystem_name, filesystem_path, - render_view_host_, &file_path, &error_)) { + render_view_host_, &file_path, &error_)) return false; - } result_.reset(base::Value::CreateStringValue(file_path.value())); return true; } +bool FileSystemEntryFunction::HasFileSystemWritePermission() { + const extensions::Extension* extension = GetExtension(); + if (!extension) + return false; + + return extension->HasAPIPermission(APIPermission::kFileSystemWrite); +} + +void FileSystemEntryFunction::CheckWritableFile(const FilePath& path) { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); + if (DoCheckWritableFile(path)) { + content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, + base::Bind(&FileSystemEntryFunction::RegisterFileSystemAndSendResponse, + this, path, WRITABLE)); + return; + } + + content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, + base::Bind(&FileSystemEntryFunction::HandleWritableFileError, this)); +} + +void FileSystemEntryFunction::RegisterFileSystemAndSendResponse( + const FilePath& path, EntryType entry_type) { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + std::set<FilePath> filesets; + filesets.insert(path); + + fileapi::IsolatedContext* isolated_context = + fileapi::IsolatedContext::GetInstance(); + DCHECK(isolated_context); + std::string filesystem_id = isolated_context->RegisterIsolatedFileSystem( + filesets); + + content::ChildProcessSecurityPolicy* policy = + content::ChildProcessSecurityPolicy::GetInstance(); + int renderer_id = render_view_host_->GetProcess()->GetID(); + if (entry_type == WRITABLE) + policy->GrantReadWriteFileSystem(renderer_id, filesystem_id); + else + policy->GrantReadFileSystem(renderer_id, filesystem_id); + + // We only need file level access for reading FileEntries. Saving FileEntries + // just needs the file system to have read/write access, which is granted + // above if required. + if (!policy->CanReadFile(renderer_id, path)) + policy->GrantReadFile(renderer_id, path); + + DictionaryValue* dict = new DictionaryValue(); + result_.reset(dict); + dict->SetString("fileSystemId", filesystem_id); + dict->SetString("baseName", path.BaseName().AsUTF8Unsafe()); + SendResponse(true); +} + +void FileSystemEntryFunction::HandleWritableFileError() { + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + error_ = kWritableFileError; + SendResponse(false); +} + +bool FileSystemGetWritableFileEntryFunction::RunImpl() { + std::string filesystem_name; + std::string filesystem_path; + EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &filesystem_name)); + EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &filesystem_path)); + + if (!HasFileSystemWritePermission()) { + error_ = kRequiresFileSystemWriteError; + return false; + } + + FilePath path; + if (!GetFilePathOfFileEntry(filesystem_name, filesystem_path, + render_view_host_, &path, &error_)) + return false; + + content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE, + base::Bind(&FileSystemGetWritableFileEntryFunction::CheckWritableFile, + this, path)); + return true; +} + // Handles showing a dialog to the user to ask for the filename for a file to // save or open. -class FileSystemPickerFunction::FilePicker : public SelectFileDialog::Listener { +class FileSystemChooseFileFunction::FilePicker + : public SelectFileDialog::Listener { public: - FilePicker(FileSystemPickerFunction* function, + FilePicker(FileSystemChooseFileFunction* function, content::WebContents* web_contents, const FilePath& suggested_path, - bool for_save) + SelectFileDialog::Type picker_type, + EntryType entry_type) : suggested_path_(suggested_path), - for_save_(for_save), + entry_type_(entry_type), function_(function) { select_file_dialog_ = SelectFileDialog::Create(this); SelectFileDialog::FileTypeInfo file_type_info; @@ -132,21 +220,21 @@ class FileSystemPickerFunction::FilePicker : public SelectFileDialog::Listener { if (g_skip_picker_for_test) { if (g_path_to_be_picked_for_test) { content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, - base::Bind(&FileSystemPickerFunction::FilePicker::FileSelected, + base::Bind( + &FileSystemChooseFileFunction::FilePicker::FileSelected, base::Unretained(this), *g_path_to_be_picked_for_test, 1, static_cast<void*>(NULL))); } else { content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, base::Bind( - &FileSystemPickerFunction::FilePicker::FileSelectionCanceled, + &FileSystemChooseFileFunction::FilePicker:: + FileSelectionCanceled, base::Unretained(this), static_cast<void*>(NULL))); } return; } - select_file_dialog_->SelectFile(for_save ? - SelectFileDialog::SELECT_SAVEAS_FILE : - SelectFileDialog::SELECT_OPEN_FILE, + select_file_dialog_->SelectFile(picker_type, string16(), suggested_path, &file_type_info, 0, FILE_PATH_LITERAL(""), @@ -160,7 +248,7 @@ class FileSystemPickerFunction::FilePicker : public SelectFileDialog::Listener { virtual void FileSelected(const FilePath& path, int index, void* params) OVERRIDE { - function_->FileSelected(path, for_save_); + function_->FileSelected(path, entry_type_); delete this; } @@ -171,19 +259,18 @@ class FileSystemPickerFunction::FilePicker : public SelectFileDialog::Listener { FilePath suggested_path_; - // for_save_ is false when using the picker to open a file, and true - // when saving. It affects the style of the dialog and also what happens - // after a file is selected by the user. - bool for_save_; + EntryType entry_type_; scoped_refptr<SelectFileDialog> select_file_dialog_; - scoped_refptr<FileSystemPickerFunction> function_; + scoped_refptr<FileSystemChooseFileFunction> function_; DISALLOW_COPY_AND_ASSIGN(FilePicker); }; -bool FileSystemPickerFunction::ShowPicker(const FilePath& suggested_path, - bool for_save) { +bool FileSystemChooseFileFunction::ShowPicker( + const FilePath& suggested_path, + SelectFileDialog::Type picker_type, + EntryType entry_type) { ShellWindowRegistry* registry = ShellWindowRegistry::Get(profile()); DCHECK(registry); ShellWindow* shell_window = registry->GetShellWindowForRenderViewHost( @@ -197,124 +284,72 @@ bool FileSystemPickerFunction::ShowPicker(const FilePath& suggested_path, // its destruction (and subsequent sending of the function response) until the // user has selected a file or cancelled the picker. At that point, the picker // will delete itself, which will also free the function instance. - new FilePicker(this, shell_window->web_contents(), suggested_path, for_save); + new FilePicker(this, shell_window->web_contents(), suggested_path, + picker_type, entry_type); return true; } // static -void FileSystemPickerFunction::SkipPickerAndAlwaysSelectPathForTest( +void FileSystemChooseFileFunction::SkipPickerAndAlwaysSelectPathForTest( FilePath* path) { g_skip_picker_for_test = true; g_path_to_be_picked_for_test = path; } // static -void FileSystemPickerFunction::SkipPickerAndAlwaysCancelForTest() { +void FileSystemChooseFileFunction::SkipPickerAndAlwaysCancelForTest() { g_skip_picker_for_test = true; g_path_to_be_picked_for_test = NULL; } // static -void FileSystemPickerFunction::StopSkippingPickerForTest() { +void FileSystemChooseFileFunction::StopSkippingPickerForTest() { g_skip_picker_for_test = false; } -void FileSystemPickerFunction::FileSelected(const FilePath& path, - bool for_save) { - if (for_save) { +void FileSystemChooseFileFunction::FileSelected(const FilePath& path, + EntryType entry_type) { + if (entry_type == WRITABLE) { content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE, - base::Bind(&FileSystemPickerFunction::CheckWritableFile, this, path)); + base::Bind(&FileSystemChooseFileFunction::CheckWritableFile, + this, path)); return; } // Don't need to check the file, it's for reading. - RegisterFileSystemAndSendResponse(path, false); + RegisterFileSystemAndSendResponse(path, READ_ONLY); } -void FileSystemPickerFunction::FileSelectionCanceled() { +void FileSystemChooseFileFunction::FileSelectionCanceled() { error_ = kUserCancelled; SendResponse(false); } -void FileSystemPickerFunction::CheckWritableFile(const FilePath& path) { - DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); - if (DoCheckWritableFile(path)) { - content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, - base::Bind(&FileSystemPickerFunction::RegisterFileSystemAndSendResponse, - this, path, true)); - return; - } - - content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, - base::Bind(&FileSystemPickerFunction::HandleWritableFileError, this)); -} - -void FileSystemPickerFunction::RegisterFileSystemAndSendResponse( - const FilePath& path, bool for_save) { - DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); - std::set<FilePath> filesets; - filesets.insert(path); - - fileapi::IsolatedContext* isolated_context = - fileapi::IsolatedContext::GetInstance(); - DCHECK(isolated_context); - std::string filesystem_id = isolated_context->RegisterIsolatedFileSystem( - filesets); - - content::ChildProcessSecurityPolicy* policy = - content::ChildProcessSecurityPolicy::GetInstance(); - int renderer_id = render_view_host_->GetProcess()->GetID(); - if (for_save) - policy->GrantReadWriteFileSystem(renderer_id, filesystem_id); - else - policy->GrantReadFileSystem(renderer_id, filesystem_id); - - // We only need file level access for reading FileEntries. Saving FileEntries - // just needs the file system to have read/write access, which is granted - // above if required. - if (!policy->CanReadFile(renderer_id, path)) - policy->GrantReadFile(renderer_id, path); - - DictionaryValue* dict = new DictionaryValue(); - result_.reset(dict); - dict->SetString("fileSystemId", filesystem_id); - dict->SetString("baseName", path.BaseName().AsUTF8Unsafe()); - SendResponse(true); -} - -void FileSystemPickerFunction::HandleWritableFileError() { - DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); - error_ = kWritableFileError; - SendResponse(false); -} - -bool FileSystemGetWritableFileEntryFunction::RunImpl() { - std::string filesystem_name; - std::string filesystem_path; - EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &filesystem_name)); - EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &filesystem_path)); - - FilePath suggested_path; - if (!GetFilePathOfFileEntry(filesystem_name, filesystem_path, - render_view_host_, &suggested_path, &error_)) { - return false; - } - - return ShowPicker(suggested_path, true); -} - bool FileSystemChooseFileFunction::RunImpl() { scoped_ptr<ChooseFile::Params> params(ChooseFile::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params.get()); - bool for_save = false; + EntryType entry_type = READ_ONLY; + SelectFileDialog::Type picker_type = SelectFileDialog::SELECT_OPEN_FILE; file_system::ChooseFileOptions* options = params->options.get(); - if (options) { - if (options->type.get() && *options->type == kSaveFileOption) - for_save = true; + if (options && options->type.get()) { + if (*options->type == kOpenWritableFileOption) { + entry_type = WRITABLE; + } else if (*options->type == kSaveFileOption) { + entry_type = WRITABLE; + picker_type = SelectFileDialog::SELECT_SAVEAS_FILE; + } else if (*options->type != kOpenFileOption) { + error_ = kUnknownChooseFileType; + return false; + } + } + + if (entry_type == WRITABLE && !HasFileSystemWritePermission()) { + error_ = kRequiresFileSystemWriteError; + return false; } - return ShowPicker(FilePath(), for_save); + return ShowPicker(FilePath(), picker_type, entry_type); } } // namespace extensions diff --git a/chrome/browser/extensions/api/file_system/file_system_api.h b/chrome/browser/extensions/api/file_system/file_system_api.h index 7cc24db7..ec3293d 100644 --- a/chrome/browser/extensions/api/file_system/file_system_api.h +++ b/chrome/browser/extensions/api/file_system/file_system_api.h @@ -7,6 +7,7 @@ #pragma once #include "chrome/browser/extensions/extension_function.h" +#include "chrome/browser/ui/select_file_dialog.h" namespace extensions { @@ -19,39 +20,33 @@ class FileSystemGetDisplayPathFunction : public SyncExtensionFunction { virtual bool RunImpl() OVERRIDE; }; -class FileSystemPickerFunction : public AsyncExtensionFunction { - public: - // Allow picker UI to be skipped in testing. - static void SkipPickerAndAlwaysSelectPathForTest(FilePath* path); - static void SkipPickerAndAlwaysCancelForTest(); - static void StopSkippingPickerForTest(); - +class FileSystemEntryFunction : public AsyncExtensionFunction { protected: - class FilePicker; + enum EntryType { + READ_ONLY, + WRITABLE + }; - virtual ~FileSystemPickerFunction() {} - bool ShowPicker(const FilePath& suggested_path, bool for_save); + virtual ~FileSystemEntryFunction() {} - private: - // FileSelected and FileSelectionCanceled are called by the file picker. - void FileSelected(const FilePath& path, bool for_save); - void FileSelectionCanceled(); + bool HasFileSystemWritePermission(); - // called on the FILE thread. This is only called when a file is being chosen - // to save. The function will ensure the file exists, creating it if + // Called on the FILE thread. This is called when a writable file entry is + // being returned. The function will ensure the file exists, creating it if // necessary, and also check that the file is not a link. void CheckWritableFile(const FilePath& path); // This will finish the choose file process. This is either called directly // from FileSelected, or from CreateFileIfNecessary. It is called on the UI // thread. - void RegisterFileSystemAndSendResponse(const FilePath& path, bool for_save); + void RegisterFileSystemAndSendResponse(const FilePath& path, + EntryType entry_type); // called on the UI thread if there is a problem checking a writable file. void HandleWritableFileError(); }; -class FileSystemGetWritableFileEntryFunction : public FileSystemPickerFunction { +class FileSystemGetWritableFileEntryFunction : public FileSystemEntryFunction { public: DECLARE_EXTENSION_FUNCTION_NAME("fileSystem.getWritableFileEntry"); @@ -60,13 +55,28 @@ class FileSystemGetWritableFileEntryFunction : public FileSystemPickerFunction { virtual bool RunImpl() OVERRIDE; }; -class FileSystemChooseFileFunction : public FileSystemPickerFunction { +class FileSystemChooseFileFunction : public FileSystemEntryFunction { public: + // Allow picker UI to be skipped in testing. + static void SkipPickerAndAlwaysSelectPathForTest(FilePath* path); + static void SkipPickerAndAlwaysCancelForTest(); + static void StopSkippingPickerForTest(); + DECLARE_EXTENSION_FUNCTION_NAME("fileSystem.chooseFile"); protected: + class FilePicker; + virtual ~FileSystemChooseFileFunction() {} virtual bool RunImpl() OVERRIDE; + bool ShowPicker(const FilePath& suggested_path, + SelectFileDialog::Type picker_type, + EntryType entry_type); + + private: + // FileSelected and FileSelectionCanceled are called by the file picker. + void FileSelected(const FilePath& path, EntryType entry_type); + void FileSelectionCanceled(); }; } // namespace extensions diff --git a/chrome/browser/extensions/api/file_system/file_system_apitest.cc b/chrome/browser/extensions/api/file_system/file_system_apitest.cc index 68cf254..5142d99 100644 --- a/chrome/browser/extensions/api/file_system/file_system_apitest.cc +++ b/chrome/browser/extensions/api/file_system/file_system_apitest.cc @@ -6,41 +6,98 @@ #include "chrome/browser/extensions/api/file_system/file_system_api.h" #include "chrome/browser/extensions/platform_app_browsertest_util.h" +using extensions::FileSystemChooseFileFunction; + class FileSystemApiTest : public PlatformAppBrowserTest { public: virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { PlatformAppBrowserTest::SetUpCommandLine(command_line); - test_file_folder_ = test_data_dir_.AppendASCII("api_test") + test_root_folder_ = test_data_dir_.AppendASCII("api_test") .AppendASCII("file_system"); } virtual void TearDown() OVERRIDE { - extensions::FileSystemPickerFunction::StopSkippingPickerForTest(); + FileSystemChooseFileFunction::StopSkippingPickerForTest(); PlatformAppBrowserTest::TearDown(); }; protected: - FilePath test_file_folder_; + FilePath TempFilePath(const std::string& destination_name, bool copy_gold) { + if (!temp_dir_.CreateUniqueTempDir()) { + ADD_FAILURE() << "CreateUniqueTempDir failed"; + return FilePath(); + } + FilePath destination = temp_dir_.path().AppendASCII(destination_name); + if (copy_gold) { + FilePath source = test_root_folder_.AppendASCII("gold.txt"); + EXPECT_TRUE(file_util::CopyFile(source, destination)); + } + return destination; + } + + FilePath test_root_folder_; + ScopedTempDir temp_dir_; }; IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiGetDisplayPath) { - FilePath test_file = test_file_folder_.AppendASCII("open_existing.txt"); - extensions::FileSystemPickerFunction::SkipPickerAndAlwaysSelectPathForTest( + FilePath test_file = test_root_folder_.AppendASCII("gold.txt"); + FileSystemChooseFileFunction::SkipPickerAndAlwaysSelectPathForTest( &test_file); ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/get_display_path")) << message_; } IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiOpenExistingFileTest) { - FilePath test_file = test_file_folder_.AppendASCII("open_existing.txt"); - extensions::FileSystemPickerFunction::SkipPickerAndAlwaysSelectPathForTest( + FilePath test_file = TempFilePath("open_existing.txt", true); + ASSERT_FALSE(test_file.empty()); + FileSystemChooseFileFunction::SkipPickerAndAlwaysSelectPathForTest( &test_file); ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/open_existing")) << message_; } +IN_PROC_BROWSER_TEST_F(FileSystemApiTest, + FileSystemApiInvalidChooseFileTypeTest) { + FilePath test_file = TempFilePath("open_existing.txt", true); + ASSERT_FALSE(test_file.empty()); + FileSystemChooseFileFunction::SkipPickerAndAlwaysSelectPathForTest( + &test_file); + ASSERT_TRUE(RunPlatformAppTest( + "api_test/file_system/invalid_choose_file_type")) << message_; +} + +IN_PROC_BROWSER_TEST_F(FileSystemApiTest, + FileSystemApiOpenExistingFileWithWriteTest) { + FilePath test_file = TempFilePath("open_existing.txt", true); + ASSERT_FALSE(test_file.empty()); + FileSystemChooseFileFunction::SkipPickerAndAlwaysSelectPathForTest( + &test_file); + ASSERT_TRUE(RunPlatformAppTest( + "api_test/file_system/open_existing_with_write")) << message_; +} + +IN_PROC_BROWSER_TEST_F(FileSystemApiTest, + FileSystemApiOpenWritableExistingFileTest) { + FilePath test_file = TempFilePath("open_existing.txt", true); + ASSERT_FALSE(test_file.empty()); + FileSystemChooseFileFunction::SkipPickerAndAlwaysSelectPathForTest( + &test_file); + ASSERT_TRUE(RunPlatformAppTest( + "api_test/file_system/open_writable_existing")) << message_; +} + +IN_PROC_BROWSER_TEST_F(FileSystemApiTest, + FileSystemApiOpenWritableExistingFileWithWriteTest) { + FilePath test_file = TempFilePath("open_existing.txt", true); + ASSERT_FALSE(test_file.empty()); + FileSystemChooseFileFunction::SkipPickerAndAlwaysSelectPathForTest( + &test_file); + ASSERT_TRUE(RunPlatformAppTest( + "api_test/file_system/open_writable_existing_with_write")) << message_; +} + IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiOpenCancelTest) { - extensions::FileSystemPickerFunction::SkipPickerAndAlwaysCancelForTest(); + FileSystemChooseFileFunction::SkipPickerAndAlwaysCancelForTest(); ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/open_cancel")) << message_; } @@ -51,28 +108,45 @@ IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiOpenBackgroundTest) { } IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiSaveNewFileTest) { - FilePath test_file = test_file_folder_.AppendASCII("save_new.txt"); - // Make sure test file path does not exist. - ASSERT_TRUE(file_util::Delete(test_file, false)); - extensions::FileSystemPickerFunction::SkipPickerAndAlwaysSelectPathForTest( + FilePath test_file = TempFilePath("save_new.txt", false); + ASSERT_FALSE(test_file.empty()); + FileSystemChooseFileFunction::SkipPickerAndAlwaysSelectPathForTest( &test_file); ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/save_new")) << message_; } IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiSaveExistingFileTest) { - FilePath test_file = test_file_folder_.AppendASCII("save_existing.txt"); - // Replace test save file to make sure it's pristine. - ASSERT_TRUE(file_util::CopyFile( - test_file_folder_.AppendASCII("open_existing.txt"), test_file)); - extensions::FileSystemPickerFunction::SkipPickerAndAlwaysSelectPathForTest( + FilePath test_file = TempFilePath("save_existing.txt", true); + ASSERT_FALSE(test_file.empty()); + FileSystemChooseFileFunction::SkipPickerAndAlwaysSelectPathForTest( &test_file); ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/save_existing")) << message_; } +IN_PROC_BROWSER_TEST_F(FileSystemApiTest, + FileSystemApiSaveNewFileWithWriteTest) { + FilePath test_file = TempFilePath("save_new.txt", false); + ASSERT_FALSE(test_file.empty()); + FileSystemChooseFileFunction::SkipPickerAndAlwaysSelectPathForTest( + &test_file); + ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/save_new_with_write")) + << message_; +} + +IN_PROC_BROWSER_TEST_F(FileSystemApiTest, + FileSystemApiSaveExistingFileWithWriteTest) { + FilePath test_file = TempFilePath("save_existing.txt", true); + ASSERT_FALSE(test_file.empty()); + FileSystemChooseFileFunction::SkipPickerAndAlwaysSelectPathForTest( + &test_file); + ASSERT_TRUE(RunPlatformAppTest( + "api_test/file_system/save_existing_with_write")) << message_; +} + IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiSaveCancelTest) { - extensions::FileSystemPickerFunction::SkipPickerAndAlwaysCancelForTest(); + FileSystemChooseFileFunction::SkipPickerAndAlwaysCancelForTest(); ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/save_cancel")) << message_; } @@ -81,3 +155,23 @@ IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiSaveBackgroundTest) { ASSERT_TRUE(RunPlatformAppTest("api_test/file_system/save_background")) << message_; } + +IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiGetWritableTest) { + FilePath test_file = TempFilePath("writable.txt", true); + ASSERT_FALSE(test_file.empty()); + FileSystemChooseFileFunction::SkipPickerAndAlwaysSelectPathForTest( + &test_file); + ASSERT_TRUE(RunPlatformAppTest( + "api_test/file_system/get_writable_file_entry")) << message_; +} + +IN_PROC_BROWSER_TEST_F(FileSystemApiTest, + FileSystemApiGetWritableWithWriteTest) { + FilePath test_file = TempFilePath("writable.txt", true); + ASSERT_FALSE(test_file.empty()); + FileSystemChooseFileFunction::SkipPickerAndAlwaysSelectPathForTest( + &test_file); + ASSERT_TRUE(RunPlatformAppTest( + "api_test/file_system/get_writable_file_entry_with_write")) << message_; +} + diff --git a/chrome/common/extensions/api/_permission_features.json b/chrome/common/extensions/api/_permission_features.json index 569c608..8888066 100644 --- a/chrome/common/extensions/api/_permission_features.json +++ b/chrome/common/extensions/api/_permission_features.json @@ -124,6 +124,10 @@ "channel": "dev", "extension_types": ["platform_app"] }, + "fileSystemWrite": { + "channel": "dev", + "extension_types": ["platform_app"] + }, "geolocation": { "channel": "stable", "extension_types": [ diff --git a/chrome/common/extensions/api/file_system.idl b/chrome/common/extensions/api/file_system.idl index 0de28ff..b92df0e 100644 --- a/chrome/common/extensions/api/file_system.idl +++ b/chrome/common/extensions/api/file_system.idl @@ -6,7 +6,12 @@ namespace fileSystem { dictionary ChooseFileOptions { - // type can be 'openFile' or 'saveFile'. Default is 'openFile'. + // Valid types are 'openFile', 'openWritableFile' or 'saveFile'. Both + // 'openFile' and 'openWritableFile' will prompt the user to open an + // existing file, with 'openFile' returning a read-only FileEntry on + // success. 'saveFile' will prompt the user to choose an existing file or + // a new file, and will return a writable FileEntry. The default is + // 'openFile'. DOMString? type; }; callback GetDisplayPathCallback = void (DOMString displayPath); diff --git a/chrome/common/extensions/docs/apps/fileSystem.html b/chrome/common/extensions/docs/apps/fileSystem.html index 0d87fec..2511fe5 100644 --- a/chrome/common/extensions/docs/apps/fileSystem.html +++ b/chrome/common/extensions/docs/apps/fileSystem.html @@ -578,7 +578,7 @@ </div> </em> </dt> - <dd>type can be 'openFile' or 'saveFile'. Default is 'openFile'.</dd> + <dd>Valid types are 'openFile', 'openWritableFile' or 'saveFile'. Both 'openFile' and 'openWritableFile' will prompt the user to open an existing file, with 'openFile' returning a read-only FileEntry on success. 'saveFile' will prompt the user to choose an existing file or a new file, and will return a writable FileEntry. The default is 'openFile'.</dd> <!-- OBJECT PROPERTIES --> <!-- OBJECT METHODS --> <!-- OBJECT EVENT FIELDS --> diff --git a/chrome/common/extensions/docs/extensions/fileSystem.html b/chrome/common/extensions/docs/extensions/fileSystem.html index 1d90817..b771f24 100644 --- a/chrome/common/extensions/docs/extensions/fileSystem.html +++ b/chrome/common/extensions/docs/extensions/fileSystem.html @@ -725,7 +725,7 @@ </div> </em> </dt> - <dd>type can be 'openFile' or 'saveFile'. Default is 'openFile'.</dd> + <dd>Valid types are 'openFile', 'openWritableFile' or 'saveFile'. Both 'openFile' and 'openWritableFile' will prompt the user to open an existing file, with 'openFile' returning a read-only FileEntry on success. 'saveFile' will prompt the user to choose an existing file or a new file, and will return a writable FileEntry. The default is 'openFile'.</dd> <!-- OBJECT PROPERTIES --> <!-- OBJECT METHODS --> <!-- OBJECT EVENT FIELDS --> diff --git a/chrome/common/extensions/permissions/api_permission.cc b/chrome/common/extensions/permissions/api_permission.cc index a102a4c..753b356 100644 --- a/chrome/common/extensions/permissions/api_permission.cc +++ b/chrome/common/extensions/permissions/api_permission.cc @@ -86,7 +86,6 @@ void APIPermission::RegisterAllPermissions( { kContextMenus, "contextMenus" }, { kCookie, "cookies" }, { kFileBrowserHandler, "fileBrowserHandler", kFlagCannotBeOptional }, - { kFileSystem, "fileSystem" }, { kHistory, "history", kFlagNone, IDS_EXTENSION_PROMPT_WARNING_BROWSING_HISTORY, PermissionMessage::kBrowsingHistory }, @@ -162,6 +161,10 @@ void APIPermission::RegisterAllPermissions( { kVideoCapture, "videoCapture", kFlagNone, IDS_EXTENSION_PROMPT_WARNING_VIDEO_CAPTURE, PermissionMessage::kVideoCapture }, + { kFileSystem, "fileSystem" }, + { kFileSystemWrite, "fileSystemWrite", kFlagNone, + IDS_EXTENSION_PROMPT_WARNING_FILE_SYSTEM_WRITE, + PermissionMessage::kFileSystemWrite }, }; for (size_t i = 0; i < ARRAYSIZE_UNSAFE(PermissionsToRegister); ++i) { diff --git a/chrome/common/extensions/permissions/api_permission.h b/chrome/common/extensions/permissions/api_permission.h index b5d9f63..917833a 100644 --- a/chrome/common/extensions/permissions/api_permission.h +++ b/chrome/common/extensions/permissions/api_permission.h @@ -50,6 +50,7 @@ class APIPermission { kFileBrowserHandlerInternal, kFileBrowserPrivate, kFileSystem, + kFileSystemWrite, kGeolocation, kHistory, kIdle, diff --git a/chrome/common/extensions/permissions/permission_message.h b/chrome/common/extensions/permissions/permission_message.h index e8710af..3ab22da 100644 --- a/chrome/common/extensions/permissions/permission_message.h +++ b/chrome/common/extensions/permissions/permission_message.h @@ -47,6 +47,7 @@ class PermissionMessage { kAudioCapture, kVideoCapture, kDownloads, + kFileSystemWrite, kEnumBoundary }; diff --git a/chrome/test/data/extensions/api_test/file_system/get_display_path/manifest.json b/chrome/test/data/extensions/api_test/file_system/get_display_path/manifest.json index c5120a5..62c24ef 100644 --- a/chrome/test/data/extensions/api_test/file_system/get_display_path/manifest.json +++ b/chrome/test/data/extensions/api_test/file_system/get_display_path/manifest.json @@ -10,7 +10,6 @@ }, "permissions": [ "experimental", - "appWindow", "fileSystem" ] } diff --git a/chrome/test/data/extensions/api_test/file_system/get_display_path/test.js b/chrome/test/data/extensions/api_test/file_system/get_display_path/test.js index 0836e7a..292ed7e 100644 --- a/chrome/test/data/extensions/api_test/file_system/get_display_path/test.js +++ b/chrome/test/data/extensions/api_test/file_system/get_display_path/test.js @@ -5,12 +5,12 @@ chrome.test.runTests([ function getDisplayPath() { chrome.fileSystem.chooseFile(chrome.test.callbackPass(function(entry) { - chrome.test.assertEq('open_existing.txt', entry.name); + chrome.test.assertEq('gold.txt', entry.name); // Test that we can get the display path of the file. chrome.fileSystem.getDisplayPath(entry, chrome.test.callbackPass( function(path) { chrome.test.assertTrue(path.indexOf("file_system") >= 0); - chrome.test.assertTrue(path.indexOf("open_existing.txt") >= 0); + chrome.test.assertTrue(path.indexOf("gold.txt") >= 0); })); })); } diff --git a/chrome/test/data/extensions/api_test/file_system/get_writable_file_entry/background.js b/chrome/test/data/extensions/api_test/file_system/get_writable_file_entry/background.js new file mode 100644 index 0000000..40ec2b7 --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/get_writable_file_entry/background.js @@ -0,0 +1,9 @@ +// Copyright (c) 2012 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. + +function onLaunched() { + chrome.appWindow.create('test.html'); +} + +chrome.experimental.app.onLaunched.addListener(onLaunched); diff --git a/chrome/test/data/extensions/api_test/file_system/get_writable_file_entry/manifest.json b/chrome/test/data/extensions/api_test/file_system/get_writable_file_entry/manifest.json new file mode 100644 index 0000000..be55801 --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/get_writable_file_entry/manifest.json @@ -0,0 +1,15 @@ +{ + "name": "chrome.fileSystem get writable file entry", + "version": "0.1", + "manifest_version": 2, + "description": "Test for chrome.fileSystem.getWritableFileEntry", + "app": { + "background": { + "scripts": ["background.js"] + } + }, + "permissions": [ + "experimental", + "fileSystem" + ] +} diff --git a/chrome/test/data/extensions/api_test/file_system/get_writable_file_entry/test.html b/chrome/test/data/extensions/api_test/file_system/get_writable_file_entry/test.html new file mode 100644 index 0000000..8d7d1db --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/get_writable_file_entry/test.html @@ -0,0 +1,3 @@ +<html> +<script src="test.js"></script> +</html> diff --git a/chrome/test/data/extensions/api_test/file_system/get_writable_file_entry/test.js b/chrome/test/data/extensions/api_test/file_system/get_writable_file_entry/test.js new file mode 100644 index 0000000..35f270c --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/get_writable_file_entry/test.js @@ -0,0 +1,14 @@ +// Copyright (c) 2012 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. + +chrome.test.runTests([ + function getWritableEntry() { + chrome.fileSystem.chooseFile(chrome.test.callbackPass(function(entry) { + chrome.test.assertEq('writable.txt', entry.name); + // Test that we can get the display path of the file. + chrome.fileSystem.getWritableFileEntry(entry, chrome.test.callbackFail( + 'Operation requires fileSystemWrite permission', function() {})); + })); + } +]); diff --git a/chrome/test/data/extensions/api_test/file_system/get_writable_file_entry_with_write/background.js b/chrome/test/data/extensions/api_test/file_system/get_writable_file_entry_with_write/background.js new file mode 100644 index 0000000..40ec2b7 --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/get_writable_file_entry_with_write/background.js @@ -0,0 +1,9 @@ +// Copyright (c) 2012 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. + +function onLaunched() { + chrome.appWindow.create('test.html'); +} + +chrome.experimental.app.onLaunched.addListener(onLaunched); diff --git a/chrome/test/data/extensions/api_test/file_system/get_writable_file_entry_with_write/manifest.json b/chrome/test/data/extensions/api_test/file_system/get_writable_file_entry_with_write/manifest.json new file mode 100644 index 0000000..ff1bbdf --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/get_writable_file_entry_with_write/manifest.json @@ -0,0 +1,16 @@ +{ + "name": "chrome.fileSystem get writable file entry with write.", + "version": "0.1", + "manifest_version": 2, + "description": "Test for chrome.fileSystem.getWritableFileEntry.", + "app": { + "background": { + "scripts": ["background.js"] + } + }, + "permissions": [ + "experimental", + "fileSystem", + "fileSystemWrite" + ] +} diff --git a/chrome/test/data/extensions/api_test/file_system/get_writable_file_entry_with_write/test.html b/chrome/test/data/extensions/api_test/file_system/get_writable_file_entry_with_write/test.html new file mode 100644 index 0000000..d68c654 --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/get_writable_file_entry_with_write/test.html @@ -0,0 +1,4 @@ +<html> +<script src="test.js"></script> +<script src="test_util.js"></script> +</html> diff --git a/chrome/test/data/extensions/api_test/file_system/get_writable_file_entry_with_write/test.js b/chrome/test/data/extensions/api_test/file_system/get_writable_file_entry_with_write/test.js new file mode 100644 index 0000000..a99e602 --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/get_writable_file_entry_with_write/test.js @@ -0,0 +1,16 @@ +// Copyright (c) 2012 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. + +chrome.test.runTests([ + function getWritableEntry() { + chrome.fileSystem.chooseFile(chrome.test.callbackPass(function(entry) { + chrome.test.assertEq('writable.txt', entry.name); + // Test that we can get the display path of the file. + chrome.fileSystem.getWritableFileEntry(entry, chrome.test.callbackPass( + function(writable) { + checkEntry(writable, 'writable.txt', false, true); + })); + })); + } +]); diff --git a/chrome/test/data/extensions/api_test/file_system/get_writable_file_entry_with_write/test_util.js b/chrome/test/data/extensions/api_test/file_system/get_writable_file_entry_with_write/test_util.js new file mode 100644 index 0000000..479ef7f --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/get_writable_file_entry_with_write/test_util.js @@ -0,0 +1,62 @@ +// Copyright (c) 2012 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. + +// This is a duplicate of the file test_util in +// chrome/test/data/extensions/api_test/file_system + +function checkEntry(entry, expectedName, isNew, shouldBeWritable) { + chrome.test.assertEq(expectedName, entry.name); + // Test that the file can be read. + entry.file(chrome.test.callback(function(file) { + var reader = new FileReader(); + reader.onloadend = chrome.test.callbackPass(function(e) { + if (isNew) + chrome.test.assertEq(reader.result, ""); + else + chrome.test.assertEq(reader.result.indexOf("Can you see me?"), 0); + // Test that we can write to the file, or not, depending on + // |shouldBeWritable|. + entry.createWriter(function(fileWriter) { + fileWriter.onwriteend = chrome.test.callback(function(e) { + if (fileWriter.error) { + if (shouldBeWritable) { + chrome.test.fail("Error writing to file: " + + fileWriter.error.toString()); + } else { + chrome.test.succeed(); + } + } else { + if (shouldBeWritable) { + // Get a new entry and check the data got to disk. + chrome.fileSystem.chooseFile(chrome.test.callbackPass( + function(readEntry) { + readEntry.file(chrome.test.callback(function(readFile) { + var readReader = new FileReader(); + readReader.onloadend = function(e) { + chrome.test.assertEq(readReader.result.indexOf("HoHoHo!"), + 0); + chrome.test.succeed(); + }; + readReader.onerror = function(e) { + chrome.test.fail("Failed to read file after write."); + }; + readReader.readAsText(readFile); + })); + })); + } else { + chrome.test.fail( + "'Could write to file that should not be writable."); + } + } + }); + var blob = new Blob(["HoHoHo!"], {type: "text/plain"}); + fileWriter.write(blob); + }); + }); + reader.onerror = chrome.test.callback(function(e) { + chrome.test.fail("Error reading file contents."); + }); + reader.readAsText(file); + })); +} diff --git a/chrome/test/data/extensions/api_test/file_system/open_existing.txt b/chrome/test/data/extensions/api_test/file_system/gold.txt index c6604a6..c6604a6 100644 --- a/chrome/test/data/extensions/api_test/file_system/open_existing.txt +++ b/chrome/test/data/extensions/api_test/file_system/gold.txt diff --git a/chrome/test/data/extensions/api_test/file_system/invalid_choose_file_type/background.js b/chrome/test/data/extensions/api_test/file_system/invalid_choose_file_type/background.js new file mode 100644 index 0000000..40ec2b7 --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/invalid_choose_file_type/background.js @@ -0,0 +1,9 @@ +// Copyright (c) 2012 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. + +function onLaunched() { + chrome.appWindow.create('test.html'); +} + +chrome.experimental.app.onLaunched.addListener(onLaunched); diff --git a/chrome/test/data/extensions/api_test/file_system/invalid_choose_file_type/manifest.json b/chrome/test/data/extensions/api_test/file_system/invalid_choose_file_type/manifest.json new file mode 100644 index 0000000..69ca1d7 --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/invalid_choose_file_type/manifest.json @@ -0,0 +1,15 @@ +{ + "name": "chrome.fileSystem invalid choose file.", + "version": "0.1", + "manifest_version": 2, + "description": "Test for chrome.fileSystem.chooseFile invalid type.", + "app": { + "background": { + "scripts": ["background.js"] + } + }, + "permissions": [ + "experimental", + "fileSystem" + ] +} diff --git a/chrome/test/data/extensions/api_test/file_system/invalid_choose_file_type/test.html b/chrome/test/data/extensions/api_test/file_system/invalid_choose_file_type/test.html new file mode 100644 index 0000000..8d7d1db --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/invalid_choose_file_type/test.html @@ -0,0 +1,3 @@ +<html> +<script src="test.js"></script> +</html> diff --git a/chrome/test/data/extensions/api_test/file_system/invalid_choose_file_type/test.js b/chrome/test/data/extensions/api_test/file_system/invalid_choose_file_type/test.js new file mode 100644 index 0000000..ce57977 --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/invalid_choose_file_type/test.js @@ -0,0 +1,10 @@ +// Copyright (c) 2012 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. + +chrome.test.runTests([ + function saveFile() { + chrome.fileSystem.chooseFile({type: 'invalid'}, chrome.test.callbackFail( + 'Unknown type', function() {})); + } +]); diff --git a/chrome/test/data/extensions/api_test/file_system/open_cancel/manifest.json b/chrome/test/data/extensions/api_test/file_system/open_cancel/manifest.json index 9fb1f3c..928391c 100644 --- a/chrome/test/data/extensions/api_test/file_system/open_cancel/manifest.json +++ b/chrome/test/data/extensions/api_test/file_system/open_cancel/manifest.json @@ -10,7 +10,6 @@ }, "permissions": [ "experimental", - "appWindow", "fileSystem" ] } diff --git a/chrome/test/data/extensions/api_test/file_system/open_existing/manifest.json b/chrome/test/data/extensions/api_test/file_system/open_existing/manifest.json index 92c3201..ec39a44 100644 --- a/chrome/test/data/extensions/api_test/file_system/open_existing/manifest.json +++ b/chrome/test/data/extensions/api_test/file_system/open_existing/manifest.json @@ -10,7 +10,6 @@ }, "permissions": [ "experimental", - "appWindow", "fileSystem" ] } diff --git a/chrome/test/data/extensions/api_test/file_system/open_existing/test.html b/chrome/test/data/extensions/api_test/file_system/open_existing/test.html index 8d7d1db..d68c654 100644 --- a/chrome/test/data/extensions/api_test/file_system/open_existing/test.html +++ b/chrome/test/data/extensions/api_test/file_system/open_existing/test.html @@ -1,3 +1,4 @@ <html> <script src="test.js"></script> +<script src="test_util.js"></script> </html> diff --git a/chrome/test/data/extensions/api_test/file_system/open_existing/test.js b/chrome/test/data/extensions/api_test/file_system/open_existing/test.js index 0cb41e9..f126826 100644 --- a/chrome/test/data/extensions/api_test/file_system/open_existing/test.js +++ b/chrome/test/data/extensions/api_test/file_system/open_existing/test.js @@ -5,29 +5,7 @@ chrome.test.runTests([ function openFile() { chrome.fileSystem.chooseFile(chrome.test.callbackPass(function(entry) { - chrome.test.assertEq('open_existing.txt', entry.name); - // Test that the file can be read. - entry.file(chrome.test.callback(function(file) { - var reader = new FileReader(); - reader.onloadend = chrome.test.callback(function(e) { - chrome.test.assertEq(reader.result.indexOf("Can you see me?"), 0); - // Test that we cannot write to the file. - entry.createWriter(chrome.test.callback(function(fileWriter) { - fileWriter.onwriteend = chrome.test.callback(function(e) { - if (fileWriter.error) - chrome.test.succeed(); - else - chrome.test.fail("No error while writing without write access"); - }); - var blob = new Blob(['HoHoHo!'], {type: 'text/plain'}); - fileWriter.write(blob); - })); - }); - reader.onerror = chrome.test.callback(function(e) { - chrome.test.fail("Error reading file contents."); - }); - reader.readAsText(file); - })); + checkEntry(entry, 'open_existing.txt', false, false); })); } ]); diff --git a/chrome/test/data/extensions/api_test/file_system/open_existing/test_util.js b/chrome/test/data/extensions/api_test/file_system/open_existing/test_util.js new file mode 100644 index 0000000..479ef7f --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/open_existing/test_util.js @@ -0,0 +1,62 @@ +// Copyright (c) 2012 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. + +// This is a duplicate of the file test_util in +// chrome/test/data/extensions/api_test/file_system + +function checkEntry(entry, expectedName, isNew, shouldBeWritable) { + chrome.test.assertEq(expectedName, entry.name); + // Test that the file can be read. + entry.file(chrome.test.callback(function(file) { + var reader = new FileReader(); + reader.onloadend = chrome.test.callbackPass(function(e) { + if (isNew) + chrome.test.assertEq(reader.result, ""); + else + chrome.test.assertEq(reader.result.indexOf("Can you see me?"), 0); + // Test that we can write to the file, or not, depending on + // |shouldBeWritable|. + entry.createWriter(function(fileWriter) { + fileWriter.onwriteend = chrome.test.callback(function(e) { + if (fileWriter.error) { + if (shouldBeWritable) { + chrome.test.fail("Error writing to file: " + + fileWriter.error.toString()); + } else { + chrome.test.succeed(); + } + } else { + if (shouldBeWritable) { + // Get a new entry and check the data got to disk. + chrome.fileSystem.chooseFile(chrome.test.callbackPass( + function(readEntry) { + readEntry.file(chrome.test.callback(function(readFile) { + var readReader = new FileReader(); + readReader.onloadend = function(e) { + chrome.test.assertEq(readReader.result.indexOf("HoHoHo!"), + 0); + chrome.test.succeed(); + }; + readReader.onerror = function(e) { + chrome.test.fail("Failed to read file after write."); + }; + readReader.readAsText(readFile); + })); + })); + } else { + chrome.test.fail( + "'Could write to file that should not be writable."); + } + } + }); + var blob = new Blob(["HoHoHo!"], {type: "text/plain"}); + fileWriter.write(blob); + }); + }); + reader.onerror = chrome.test.callback(function(e) { + chrome.test.fail("Error reading file contents."); + }); + reader.readAsText(file); + })); +} diff --git a/chrome/test/data/extensions/api_test/file_system/open_existing_with_write/background.js b/chrome/test/data/extensions/api_test/file_system/open_existing_with_write/background.js new file mode 100644 index 0000000..40ec2b7 --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/open_existing_with_write/background.js @@ -0,0 +1,9 @@ +// Copyright (c) 2012 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. + +function onLaunched() { + chrome.appWindow.create('test.html'); +} + +chrome.experimental.app.onLaunched.addListener(onLaunched); diff --git a/chrome/test/data/extensions/api_test/file_system/open_existing_with_write/manifest.json b/chrome/test/data/extensions/api_test/file_system/open_existing_with_write/manifest.json new file mode 100644 index 0000000..c0104c9 --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/open_existing_with_write/manifest.json @@ -0,0 +1,16 @@ +{ + "name": "chrome.fileSystem open existing file with write", + "version": "0.1", + "manifest_version": 2, + "description": "Test for chrome.fileSystem.chooseFile opening existing file.", + "app": { + "background": { + "scripts": ["background.js"] + } + }, + "permissions": [ + "experimental", + "fileSystem", + "fileSystemWrite" + ] +} diff --git a/chrome/test/data/extensions/api_test/file_system/open_existing_with_write/test.html b/chrome/test/data/extensions/api_test/file_system/open_existing_with_write/test.html new file mode 100644 index 0000000..d68c654 --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/open_existing_with_write/test.html @@ -0,0 +1,4 @@ +<html> +<script src="test.js"></script> +<script src="test_util.js"></script> +</html> diff --git a/chrome/test/data/extensions/api_test/file_system/open_existing_with_write/test.js b/chrome/test/data/extensions/api_test/file_system/open_existing_with_write/test.js new file mode 100644 index 0000000..f126826 --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/open_existing_with_write/test.js @@ -0,0 +1,11 @@ +// Copyright (c) 2012 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. + +chrome.test.runTests([ + function openFile() { + chrome.fileSystem.chooseFile(chrome.test.callbackPass(function(entry) { + checkEntry(entry, 'open_existing.txt', false, false); + })); + } +]); diff --git a/chrome/test/data/extensions/api_test/file_system/open_existing_with_write/test_util.js b/chrome/test/data/extensions/api_test/file_system/open_existing_with_write/test_util.js new file mode 100644 index 0000000..479ef7f --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/open_existing_with_write/test_util.js @@ -0,0 +1,62 @@ +// Copyright (c) 2012 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. + +// This is a duplicate of the file test_util in +// chrome/test/data/extensions/api_test/file_system + +function checkEntry(entry, expectedName, isNew, shouldBeWritable) { + chrome.test.assertEq(expectedName, entry.name); + // Test that the file can be read. + entry.file(chrome.test.callback(function(file) { + var reader = new FileReader(); + reader.onloadend = chrome.test.callbackPass(function(e) { + if (isNew) + chrome.test.assertEq(reader.result, ""); + else + chrome.test.assertEq(reader.result.indexOf("Can you see me?"), 0); + // Test that we can write to the file, or not, depending on + // |shouldBeWritable|. + entry.createWriter(function(fileWriter) { + fileWriter.onwriteend = chrome.test.callback(function(e) { + if (fileWriter.error) { + if (shouldBeWritable) { + chrome.test.fail("Error writing to file: " + + fileWriter.error.toString()); + } else { + chrome.test.succeed(); + } + } else { + if (shouldBeWritable) { + // Get a new entry and check the data got to disk. + chrome.fileSystem.chooseFile(chrome.test.callbackPass( + function(readEntry) { + readEntry.file(chrome.test.callback(function(readFile) { + var readReader = new FileReader(); + readReader.onloadend = function(e) { + chrome.test.assertEq(readReader.result.indexOf("HoHoHo!"), + 0); + chrome.test.succeed(); + }; + readReader.onerror = function(e) { + chrome.test.fail("Failed to read file after write."); + }; + readReader.readAsText(readFile); + })); + })); + } else { + chrome.test.fail( + "'Could write to file that should not be writable."); + } + } + }); + var blob = new Blob(["HoHoHo!"], {type: "text/plain"}); + fileWriter.write(blob); + }); + }); + reader.onerror = chrome.test.callback(function(e) { + chrome.test.fail("Error reading file contents."); + }); + reader.readAsText(file); + })); +} diff --git a/chrome/test/data/extensions/api_test/file_system/open_writable_existing/background.js b/chrome/test/data/extensions/api_test/file_system/open_writable_existing/background.js new file mode 100644 index 0000000..40ec2b7 --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/open_writable_existing/background.js @@ -0,0 +1,9 @@ +// Copyright (c) 2012 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. + +function onLaunched() { + chrome.appWindow.create('test.html'); +} + +chrome.experimental.app.onLaunched.addListener(onLaunched); diff --git a/chrome/test/data/extensions/api_test/file_system/open_writable_existing/manifest.json b/chrome/test/data/extensions/api_test/file_system/open_writable_existing/manifest.json new file mode 100644 index 0000000..d1480dd --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/open_writable_existing/manifest.json @@ -0,0 +1,15 @@ +{ + "name": "chrome.fileSystem open writable file", + "version": "0.1", + "manifest_version": 2, + "description": "Test for chrome.fileSystem.chooseFile opening writable file.", + "app": { + "background": { + "scripts": ["background.js"] + } + }, + "permissions": [ + "experimental", + "fileSystem" + ] +} diff --git a/chrome/test/data/extensions/api_test/file_system/open_writable_existing/test.html b/chrome/test/data/extensions/api_test/file_system/open_writable_existing/test.html new file mode 100644 index 0000000..8d7d1db --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/open_writable_existing/test.html @@ -0,0 +1,3 @@ +<html> +<script src="test.js"></script> +</html> diff --git a/chrome/test/data/extensions/api_test/file_system/open_writable_existing/test.js b/chrome/test/data/extensions/api_test/file_system/open_writable_existing/test.js new file mode 100644 index 0000000..1c9778d --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/open_writable_existing/test.js @@ -0,0 +1,12 @@ +// Copyright (c) 2012 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. + +chrome.test.runTests([ + function openFile() { + chrome.fileSystem.chooseFile({type: 'openWritableFile'}, + chrome.test.callbackFail( + 'Operation requires fileSystemWrite permission', + function(entry) {})); + } +]); diff --git a/chrome/test/data/extensions/api_test/file_system/open_writable_existing_with_write/background.js b/chrome/test/data/extensions/api_test/file_system/open_writable_existing_with_write/background.js new file mode 100644 index 0000000..40ec2b7 --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/open_writable_existing_with_write/background.js @@ -0,0 +1,9 @@ +// Copyright (c) 2012 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. + +function onLaunched() { + chrome.appWindow.create('test.html'); +} + +chrome.experimental.app.onLaunched.addListener(onLaunched); diff --git a/chrome/test/data/extensions/api_test/file_system/open_writable_existing_with_write/manifest.json b/chrome/test/data/extensions/api_test/file_system/open_writable_existing_with_write/manifest.json new file mode 100644 index 0000000..4eeb7e9 --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/open_writable_existing_with_write/manifest.json @@ -0,0 +1,16 @@ +{ + "name": "chrome.fileSystem open writable file with write", + "version": "0.1", + "manifest_version": 2, + "description": "Test for chrome.fileSystem.chooseFile opening writable file.", + "app": { + "background": { + "scripts": ["background.js"] + } + }, + "permissions": [ + "experimental", + "fileSystem", + "fileSystemWrite" + ] +} diff --git a/chrome/test/data/extensions/api_test/file_system/open_writable_existing_with_write/test.html b/chrome/test/data/extensions/api_test/file_system/open_writable_existing_with_write/test.html new file mode 100644 index 0000000..d68c654 --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/open_writable_existing_with_write/test.html @@ -0,0 +1,4 @@ +<html> +<script src="test.js"></script> +<script src="test_util.js"></script> +</html> diff --git a/chrome/test/data/extensions/api_test/file_system/open_writable_existing_with_write/test.js b/chrome/test/data/extensions/api_test/file_system/open_writable_existing_with_write/test.js new file mode 100644 index 0000000..1428764 --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/open_writable_existing_with_write/test.js @@ -0,0 +1,12 @@ +// Copyright (c) 2012 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. + +chrome.test.runTests([ + function openFile() { + chrome.fileSystem.chooseFile({type: 'openWritableFile'}, + chrome.test.callbackPass(function(entry) { + checkEntry(entry, 'open_existing.txt', false, true); + })); + } +]); diff --git a/chrome/test/data/extensions/api_test/file_system/open_writable_existing_with_write/test_util.js b/chrome/test/data/extensions/api_test/file_system/open_writable_existing_with_write/test_util.js new file mode 100644 index 0000000..479ef7f --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/open_writable_existing_with_write/test_util.js @@ -0,0 +1,62 @@ +// Copyright (c) 2012 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. + +// This is a duplicate of the file test_util in +// chrome/test/data/extensions/api_test/file_system + +function checkEntry(entry, expectedName, isNew, shouldBeWritable) { + chrome.test.assertEq(expectedName, entry.name); + // Test that the file can be read. + entry.file(chrome.test.callback(function(file) { + var reader = new FileReader(); + reader.onloadend = chrome.test.callbackPass(function(e) { + if (isNew) + chrome.test.assertEq(reader.result, ""); + else + chrome.test.assertEq(reader.result.indexOf("Can you see me?"), 0); + // Test that we can write to the file, or not, depending on + // |shouldBeWritable|. + entry.createWriter(function(fileWriter) { + fileWriter.onwriteend = chrome.test.callback(function(e) { + if (fileWriter.error) { + if (shouldBeWritable) { + chrome.test.fail("Error writing to file: " + + fileWriter.error.toString()); + } else { + chrome.test.succeed(); + } + } else { + if (shouldBeWritable) { + // Get a new entry and check the data got to disk. + chrome.fileSystem.chooseFile(chrome.test.callbackPass( + function(readEntry) { + readEntry.file(chrome.test.callback(function(readFile) { + var readReader = new FileReader(); + readReader.onloadend = function(e) { + chrome.test.assertEq(readReader.result.indexOf("HoHoHo!"), + 0); + chrome.test.succeed(); + }; + readReader.onerror = function(e) { + chrome.test.fail("Failed to read file after write."); + }; + readReader.readAsText(readFile); + })); + })); + } else { + chrome.test.fail( + "'Could write to file that should not be writable."); + } + } + }); + var blob = new Blob(["HoHoHo!"], {type: "text/plain"}); + fileWriter.write(blob); + }); + }); + reader.onerror = chrome.test.callback(function(e) { + chrome.test.fail("Error reading file contents."); + }); + reader.readAsText(file); + })); +} diff --git a/chrome/test/data/extensions/api_test/file_system/save_background/manifest.json b/chrome/test/data/extensions/api_test/file_system/save_background/manifest.json index 6bde914..b490763 100644 --- a/chrome/test/data/extensions/api_test/file_system/save_background/manifest.json +++ b/chrome/test/data/extensions/api_test/file_system/save_background/manifest.json @@ -10,6 +10,7 @@ }, "permissions": [ "experimental", - "fileSystem" + "fileSystem", + "fileSystemWrite" ] } diff --git a/chrome/test/data/extensions/api_test/file_system/save_cancel/manifest.json b/chrome/test/data/extensions/api_test/file_system/save_cancel/manifest.json index 577d390..d7a394c 100644 --- a/chrome/test/data/extensions/api_test/file_system/save_cancel/manifest.json +++ b/chrome/test/data/extensions/api_test/file_system/save_cancel/manifest.json @@ -10,7 +10,7 @@ }, "permissions": [ "experimental", - "appWindow", - "fileSystem" + "fileSystem", + "fileSystemWrite" ] } diff --git a/chrome/test/data/extensions/api_test/file_system/save_existing/manifest.json b/chrome/test/data/extensions/api_test/file_system/save_existing/manifest.json index 226a071..17de889 100644 --- a/chrome/test/data/extensions/api_test/file_system/save_existing/manifest.json +++ b/chrome/test/data/extensions/api_test/file_system/save_existing/manifest.json @@ -10,7 +10,6 @@ }, "permissions": [ "experimental", - "appWindow", "fileSystem" ] } diff --git a/chrome/test/data/extensions/api_test/file_system/save_existing/test.js b/chrome/test/data/extensions/api_test/file_system/save_existing/test.js index 1691cfd..f9f2b48 100644 --- a/chrome/test/data/extensions/api_test/file_system/save_existing/test.js +++ b/chrome/test/data/extensions/api_test/file_system/save_existing/test.js @@ -4,48 +4,7 @@ chrome.test.runTests([ function saveFile() { - chrome.fileSystem.chooseFile({type: 'saveFile'}, chrome.test.callbackPass( - function(entry) { - chrome.test.assertEq('save_existing.txt', entry.name); - // Test that the file can be readt. - entry.file(chrome.test.callback(function(file) { - var reader = new FileReader(); - reader.onloadend = chrome.test.callbackPass(function(e) { - chrome.test.assertEq(reader.result.indexOf("Can you see me?"), 0); - // Test that we can write to the file. - entry.createWriter(function(fileWriter) { - fileWriter.onwriteend = chrome.test.callback(function(e) { - if (fileWriter.error) { - chrome.test.fail("Error writing to file: " + - fileWriter.error.toString()); - } else { - // Get a new entry and check the data got to disk. - chrome.fileSystem.chooseFile(chrome.test.callbackPass( - function(readEntry) { - readEntry.file(chrome.test.callback(function(readFile) { - var readReader = new FileReader(); - readReader.onloadend = function(e) { - chrome.test.assertEq(readReader.result.indexOf("HoHoHo!"), - 0); - chrome.test.succeed(); - }; - readReader.onerror = function(e) { - chrome.test.fail('Failed to read file after write.'); - }; - readReader.readAsText(readFile); - })); - })); - } - }); - var blob = new Blob(['HoHoHo!'], {type: 'text/plain'}); - fileWriter.write(blob); - }); - }); - reader.onerror = chrome.test.callback(function(e) { - chrome.test.fail("Error reading file contents."); - }); - reader.readAsText(file); - })); - })); + chrome.fileSystem.chooseFile({type: 'saveFile'}, chrome.test.callbackFail( + 'Operation requires fileSystemWrite permission', function() {})); } ]); diff --git a/chrome/test/data/extensions/api_test/file_system/save_existing_with_write/background.js b/chrome/test/data/extensions/api_test/file_system/save_existing_with_write/background.js new file mode 100644 index 0000000..40ec2b7 --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/save_existing_with_write/background.js @@ -0,0 +1,9 @@ +// Copyright (c) 2012 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. + +function onLaunched() { + chrome.appWindow.create('test.html'); +} + +chrome.experimental.app.onLaunched.addListener(onLaunched); diff --git a/chrome/test/data/extensions/api_test/file_system/save_existing_with_write/manifest.json b/chrome/test/data/extensions/api_test/file_system/save_existing_with_write/manifest.json new file mode 100644 index 0000000..3d483cd --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/save_existing_with_write/manifest.json @@ -0,0 +1,16 @@ +{ + "name": "chrome.fileSystem save existing file with write", + "version": "0.1", + "manifest_version": 2, + "description": "Test for chrome.fileSystem.chooseFile saving existing file.", + "app": { + "background": { + "scripts": ["background.js"] + } + }, + "permissions": [ + "experimental", + "fileSystem", + "fileSystemWrite" + ] +} diff --git a/chrome/test/data/extensions/api_test/file_system/save_existing_with_write/test.html b/chrome/test/data/extensions/api_test/file_system/save_existing_with_write/test.html new file mode 100644 index 0000000..d68c654 --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/save_existing_with_write/test.html @@ -0,0 +1,4 @@ +<html> +<script src="test.js"></script> +<script src="test_util.js"></script> +</html> diff --git a/chrome/test/data/extensions/api_test/file_system/save_existing_with_write/test.js b/chrome/test/data/extensions/api_test/file_system/save_existing_with_write/test.js new file mode 100644 index 0000000..64f3b33 --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/save_existing_with_write/test.js @@ -0,0 +1,12 @@ +// Copyright (c) 2012 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. + +chrome.test.runTests([ + function saveFile() { + chrome.fileSystem.chooseFile({type: 'saveFile'}, + chrome.test.callbackPass(function(entry) { + checkEntry(entry, 'save_existing.txt', false, true); + })); + } +]); diff --git a/chrome/test/data/extensions/api_test/file_system/save_existing_with_write/test_util.js b/chrome/test/data/extensions/api_test/file_system/save_existing_with_write/test_util.js new file mode 100644 index 0000000..479ef7f --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/save_existing_with_write/test_util.js @@ -0,0 +1,62 @@ +// Copyright (c) 2012 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. + +// This is a duplicate of the file test_util in +// chrome/test/data/extensions/api_test/file_system + +function checkEntry(entry, expectedName, isNew, shouldBeWritable) { + chrome.test.assertEq(expectedName, entry.name); + // Test that the file can be read. + entry.file(chrome.test.callback(function(file) { + var reader = new FileReader(); + reader.onloadend = chrome.test.callbackPass(function(e) { + if (isNew) + chrome.test.assertEq(reader.result, ""); + else + chrome.test.assertEq(reader.result.indexOf("Can you see me?"), 0); + // Test that we can write to the file, or not, depending on + // |shouldBeWritable|. + entry.createWriter(function(fileWriter) { + fileWriter.onwriteend = chrome.test.callback(function(e) { + if (fileWriter.error) { + if (shouldBeWritable) { + chrome.test.fail("Error writing to file: " + + fileWriter.error.toString()); + } else { + chrome.test.succeed(); + } + } else { + if (shouldBeWritable) { + // Get a new entry and check the data got to disk. + chrome.fileSystem.chooseFile(chrome.test.callbackPass( + function(readEntry) { + readEntry.file(chrome.test.callback(function(readFile) { + var readReader = new FileReader(); + readReader.onloadend = function(e) { + chrome.test.assertEq(readReader.result.indexOf("HoHoHo!"), + 0); + chrome.test.succeed(); + }; + readReader.onerror = function(e) { + chrome.test.fail("Failed to read file after write."); + }; + readReader.readAsText(readFile); + })); + })); + } else { + chrome.test.fail( + "'Could write to file that should not be writable."); + } + } + }); + var blob = new Blob(["HoHoHo!"], {type: "text/plain"}); + fileWriter.write(blob); + }); + }); + reader.onerror = chrome.test.callback(function(e) { + chrome.test.fail("Error reading file contents."); + }); + reader.readAsText(file); + })); +} diff --git a/chrome/test/data/extensions/api_test/file_system/save_new/manifest.json b/chrome/test/data/extensions/api_test/file_system/save_new/manifest.json index 0ba2bcf..6e059ea7 100644 --- a/chrome/test/data/extensions/api_test/file_system/save_new/manifest.json +++ b/chrome/test/data/extensions/api_test/file_system/save_new/manifest.json @@ -10,7 +10,6 @@ }, "permissions": [ "experimental", - "appWindow", "fileSystem" ] } diff --git a/chrome/test/data/extensions/api_test/file_system/save_new/test.js b/chrome/test/data/extensions/api_test/file_system/save_new/test.js index 6e4d22a..f9f2b48 100644 --- a/chrome/test/data/extensions/api_test/file_system/save_new/test.js +++ b/chrome/test/data/extensions/api_test/file_system/save_new/test.js @@ -4,48 +4,7 @@ chrome.test.runTests([ function saveFile() { - chrome.fileSystem.chooseFile({type: 'saveFile'}, chrome.test.callbackPass( - function(entry) { - chrome.test.assertEq('save_new.txt', entry.name); - // Test that the file can be read but has nothing in it. - entry.file(chrome.test.callback(function(file) { - var reader = new FileReader(); - reader.onloadend = chrome.test.callbackPass(function(e) { - chrome.test.assertEq(reader.result, ""); - // Test that we can write to the file. - entry.createWriter(function(fileWriter) { - fileWriter.onwriteend = chrome.test.callback(function(e) { - if (fileWriter.error) { - chrome.test.fail("Error writing to file: " + - fileWriter.error.toString()); - } else { - // Get a new entry and check the data got to disk. - chrome.fileSystem.chooseFile(chrome.test.callbackPass( - function(readEntry) { - readEntry.file(chrome.test.callback(function(readFile) { - var readReader = new FileReader(); - readReader.onloadend = function(e) { - chrome.test.assertEq(readReader.result.indexOf("HoHoHo!"), - 0); - chrome.test.succeed(); - }; - readReader.onerror = function(e) { - chrome.test.fail('Failed to read file after write.'); - }; - readReader.readAsText(readFile); - })); - })); - } - }); - var blob = new Blob(['HoHoHo!'], {type: 'text/plain'}); - fileWriter.write(blob); - }); - }); - reader.onerror = chrome.test.callback(function(e) { - chrome.test.fail("Error reading file contents."); - }); - reader.readAsText(file); - })); - })); + chrome.fileSystem.chooseFile({type: 'saveFile'}, chrome.test.callbackFail( + 'Operation requires fileSystemWrite permission', function() {})); } ]); diff --git a/chrome/test/data/extensions/api_test/file_system/save_new_with_write/background.js b/chrome/test/data/extensions/api_test/file_system/save_new_with_write/background.js new file mode 100644 index 0000000..40ec2b7 --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/save_new_with_write/background.js @@ -0,0 +1,9 @@ +// Copyright (c) 2012 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. + +function onLaunched() { + chrome.appWindow.create('test.html'); +} + +chrome.experimental.app.onLaunched.addListener(onLaunched); diff --git a/chrome/test/data/extensions/api_test/file_system/save_new_with_write/manifest.json b/chrome/test/data/extensions/api_test/file_system/save_new_with_write/manifest.json new file mode 100644 index 0000000..3f6b092 --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/save_new_with_write/manifest.json @@ -0,0 +1,16 @@ +{ + "name": "chrome.fileSystem save new file with write", + "version": "0.1", + "manifest_version": 2, + "description": "Test for chrome.fileSystem.chooseFile saving new file.", + "app": { + "background": { + "scripts": ["background.js"] + } + }, + "permissions": [ + "experimental", + "fileSystem", + "fileSystemWrite" + ] +} diff --git a/chrome/test/data/extensions/api_test/file_system/save_new_with_write/test.html b/chrome/test/data/extensions/api_test/file_system/save_new_with_write/test.html new file mode 100644 index 0000000..d68c654 --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/save_new_with_write/test.html @@ -0,0 +1,4 @@ +<html> +<script src="test.js"></script> +<script src="test_util.js"></script> +</html> diff --git a/chrome/test/data/extensions/api_test/file_system/save_new_with_write/test.js b/chrome/test/data/extensions/api_test/file_system/save_new_with_write/test.js new file mode 100644 index 0000000..b20ebc0 --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/save_new_with_write/test.js @@ -0,0 +1,12 @@ +// Copyright (c) 2012 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. + +chrome.test.runTests([ + function saveFile() { + chrome.fileSystem.chooseFile({type: 'saveFile'}, + chrome.test.callbackPass(function(entry) { + checkEntry(entry, 'save_new.txt', true, true); + })); + } +]); diff --git a/chrome/test/data/extensions/api_test/file_system/save_new_with_write/test_util.js b/chrome/test/data/extensions/api_test/file_system/save_new_with_write/test_util.js new file mode 100644 index 0000000..479ef7f --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/save_new_with_write/test_util.js @@ -0,0 +1,62 @@ +// Copyright (c) 2012 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. + +// This is a duplicate of the file test_util in +// chrome/test/data/extensions/api_test/file_system + +function checkEntry(entry, expectedName, isNew, shouldBeWritable) { + chrome.test.assertEq(expectedName, entry.name); + // Test that the file can be read. + entry.file(chrome.test.callback(function(file) { + var reader = new FileReader(); + reader.onloadend = chrome.test.callbackPass(function(e) { + if (isNew) + chrome.test.assertEq(reader.result, ""); + else + chrome.test.assertEq(reader.result.indexOf("Can you see me?"), 0); + // Test that we can write to the file, or not, depending on + // |shouldBeWritable|. + entry.createWriter(function(fileWriter) { + fileWriter.onwriteend = chrome.test.callback(function(e) { + if (fileWriter.error) { + if (shouldBeWritable) { + chrome.test.fail("Error writing to file: " + + fileWriter.error.toString()); + } else { + chrome.test.succeed(); + } + } else { + if (shouldBeWritable) { + // Get a new entry and check the data got to disk. + chrome.fileSystem.chooseFile(chrome.test.callbackPass( + function(readEntry) { + readEntry.file(chrome.test.callback(function(readFile) { + var readReader = new FileReader(); + readReader.onloadend = function(e) { + chrome.test.assertEq(readReader.result.indexOf("HoHoHo!"), + 0); + chrome.test.succeed(); + }; + readReader.onerror = function(e) { + chrome.test.fail("Failed to read file after write."); + }; + readReader.readAsText(readFile); + })); + })); + } else { + chrome.test.fail( + "'Could write to file that should not be writable."); + } + } + }); + var blob = new Blob(["HoHoHo!"], {type: "text/plain"}); + fileWriter.write(blob); + }); + }); + reader.onerror = chrome.test.callback(function(e) { + chrome.test.fail("Error reading file contents."); + }); + reader.readAsText(file); + })); +} diff --git a/chrome/test/data/extensions/api_test/file_system/test_util.js b/chrome/test/data/extensions/api_test/file_system/test_util.js new file mode 100644 index 0000000..479ef7f --- /dev/null +++ b/chrome/test/data/extensions/api_test/file_system/test_util.js @@ -0,0 +1,62 @@ +// Copyright (c) 2012 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. + +// This is a duplicate of the file test_util in +// chrome/test/data/extensions/api_test/file_system + +function checkEntry(entry, expectedName, isNew, shouldBeWritable) { + chrome.test.assertEq(expectedName, entry.name); + // Test that the file can be read. + entry.file(chrome.test.callback(function(file) { + var reader = new FileReader(); + reader.onloadend = chrome.test.callbackPass(function(e) { + if (isNew) + chrome.test.assertEq(reader.result, ""); + else + chrome.test.assertEq(reader.result.indexOf("Can you see me?"), 0); + // Test that we can write to the file, or not, depending on + // |shouldBeWritable|. + entry.createWriter(function(fileWriter) { + fileWriter.onwriteend = chrome.test.callback(function(e) { + if (fileWriter.error) { + if (shouldBeWritable) { + chrome.test.fail("Error writing to file: " + + fileWriter.error.toString()); + } else { + chrome.test.succeed(); + } + } else { + if (shouldBeWritable) { + // Get a new entry and check the data got to disk. + chrome.fileSystem.chooseFile(chrome.test.callbackPass( + function(readEntry) { + readEntry.file(chrome.test.callback(function(readFile) { + var readReader = new FileReader(); + readReader.onloadend = function(e) { + chrome.test.assertEq(readReader.result.indexOf("HoHoHo!"), + 0); + chrome.test.succeed(); + }; + readReader.onerror = function(e) { + chrome.test.fail("Failed to read file after write."); + }; + readReader.readAsText(readFile); + })); + })); + } else { + chrome.test.fail( + "'Could write to file that should not be writable."); + } + } + }); + var blob = new Blob(["HoHoHo!"], {type: "text/plain"}); + fileWriter.write(blob); + }); + }); + reader.onerror = chrome.test.callback(function(e) { + chrome.test.fail("Error reading file contents."); + }); + reader.readAsText(file); + })); +} |