summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
Diffstat (limited to 'chrome')
-rw-r--r--chrome/app/generated_resources.grd3
-rw-r--r--chrome/browser/extensions/api/file_system/file_system_api.cc239
-rw-r--r--chrome/browser/extensions/api/file_system/file_system_api.h48
-rw-r--r--chrome/browser/extensions/api/file_system/file_system_apitest.cc130
-rw-r--r--chrome/common/extensions/api/_permission_features.json4
-rw-r--r--chrome/common/extensions/api/file_system.idl7
-rw-r--r--chrome/common/extensions/docs/apps/fileSystem.html2
-rw-r--r--chrome/common/extensions/docs/extensions/fileSystem.html2
-rw-r--r--chrome/common/extensions/permissions/api_permission.cc5
-rw-r--r--chrome/common/extensions/permissions/api_permission.h1
-rw-r--r--chrome/common/extensions/permissions/permission_message.h1
-rw-r--r--chrome/test/data/extensions/api_test/file_system/get_display_path/manifest.json1
-rw-r--r--chrome/test/data/extensions/api_test/file_system/get_display_path/test.js4
-rw-r--r--chrome/test/data/extensions/api_test/file_system/get_writable_file_entry/background.js9
-rw-r--r--chrome/test/data/extensions/api_test/file_system/get_writable_file_entry/manifest.json15
-rw-r--r--chrome/test/data/extensions/api_test/file_system/get_writable_file_entry/test.html3
-rw-r--r--chrome/test/data/extensions/api_test/file_system/get_writable_file_entry/test.js14
-rw-r--r--chrome/test/data/extensions/api_test/file_system/get_writable_file_entry_with_write/background.js9
-rw-r--r--chrome/test/data/extensions/api_test/file_system/get_writable_file_entry_with_write/manifest.json16
-rw-r--r--chrome/test/data/extensions/api_test/file_system/get_writable_file_entry_with_write/test.html4
-rw-r--r--chrome/test/data/extensions/api_test/file_system/get_writable_file_entry_with_write/test.js16
-rw-r--r--chrome/test/data/extensions/api_test/file_system/get_writable_file_entry_with_write/test_util.js62
-rw-r--r--chrome/test/data/extensions/api_test/file_system/gold.txt (renamed from chrome/test/data/extensions/api_test/file_system/open_existing.txt)0
-rw-r--r--chrome/test/data/extensions/api_test/file_system/invalid_choose_file_type/background.js9
-rw-r--r--chrome/test/data/extensions/api_test/file_system/invalid_choose_file_type/manifest.json15
-rw-r--r--chrome/test/data/extensions/api_test/file_system/invalid_choose_file_type/test.html3
-rw-r--r--chrome/test/data/extensions/api_test/file_system/invalid_choose_file_type/test.js10
-rw-r--r--chrome/test/data/extensions/api_test/file_system/open_cancel/manifest.json1
-rw-r--r--chrome/test/data/extensions/api_test/file_system/open_existing/manifest.json1
-rw-r--r--chrome/test/data/extensions/api_test/file_system/open_existing/test.html1
-rw-r--r--chrome/test/data/extensions/api_test/file_system/open_existing/test.js24
-rw-r--r--chrome/test/data/extensions/api_test/file_system/open_existing/test_util.js62
-rw-r--r--chrome/test/data/extensions/api_test/file_system/open_existing_with_write/background.js9
-rw-r--r--chrome/test/data/extensions/api_test/file_system/open_existing_with_write/manifest.json16
-rw-r--r--chrome/test/data/extensions/api_test/file_system/open_existing_with_write/test.html4
-rw-r--r--chrome/test/data/extensions/api_test/file_system/open_existing_with_write/test.js11
-rw-r--r--chrome/test/data/extensions/api_test/file_system/open_existing_with_write/test_util.js62
-rw-r--r--chrome/test/data/extensions/api_test/file_system/open_writable_existing/background.js9
-rw-r--r--chrome/test/data/extensions/api_test/file_system/open_writable_existing/manifest.json15
-rw-r--r--chrome/test/data/extensions/api_test/file_system/open_writable_existing/test.html3
-rw-r--r--chrome/test/data/extensions/api_test/file_system/open_writable_existing/test.js12
-rw-r--r--chrome/test/data/extensions/api_test/file_system/open_writable_existing_with_write/background.js9
-rw-r--r--chrome/test/data/extensions/api_test/file_system/open_writable_existing_with_write/manifest.json16
-rw-r--r--chrome/test/data/extensions/api_test/file_system/open_writable_existing_with_write/test.html4
-rw-r--r--chrome/test/data/extensions/api_test/file_system/open_writable_existing_with_write/test.js12
-rw-r--r--chrome/test/data/extensions/api_test/file_system/open_writable_existing_with_write/test_util.js62
-rw-r--r--chrome/test/data/extensions/api_test/file_system/save_background/manifest.json3
-rw-r--r--chrome/test/data/extensions/api_test/file_system/save_cancel/manifest.json4
-rw-r--r--chrome/test/data/extensions/api_test/file_system/save_existing/manifest.json1
-rw-r--r--chrome/test/data/extensions/api_test/file_system/save_existing/test.js45
-rw-r--r--chrome/test/data/extensions/api_test/file_system/save_existing_with_write/background.js9
-rw-r--r--chrome/test/data/extensions/api_test/file_system/save_existing_with_write/manifest.json16
-rw-r--r--chrome/test/data/extensions/api_test/file_system/save_existing_with_write/test.html4
-rw-r--r--chrome/test/data/extensions/api_test/file_system/save_existing_with_write/test.js12
-rw-r--r--chrome/test/data/extensions/api_test/file_system/save_existing_with_write/test_util.js62
-rw-r--r--chrome/test/data/extensions/api_test/file_system/save_new/manifest.json1
-rw-r--r--chrome/test/data/extensions/api_test/file_system/save_new/test.js45
-rw-r--r--chrome/test/data/extensions/api_test/file_system/save_new_with_write/background.js9
-rw-r--r--chrome/test/data/extensions/api_test/file_system/save_new_with_write/manifest.json16
-rw-r--r--chrome/test/data/extensions/api_test/file_system/save_new_with_write/test.html4
-rw-r--r--chrome/test/data/extensions/api_test/file_system/save_new_with_write/test.js12
-rw-r--r--chrome/test/data/extensions/api_test/file_system/save_new_with_write/test_util.js62
-rw-r--r--chrome/test/data/extensions/api_test/file_system/test_util.js62
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);
+ }));
+}