Commit ba28fc47 authored by mtomasz@chromium.org's avatar mtomasz@chromium.org

[fsp] Add an option for mounting in R/W mode.

Files app fetches information whether a volume is read only or R/W from
file_manager::VolumeManager, which used to always have the isReadOnly option
set to true for any provided file system.

However, since R/W operations are now under development, we should be able to
mark a volume as R/W.

In order to achieve that, a "writable" option has been added to the File System
Provider API mount() call. The argument is by default false, so file systems
are by default read only.

TEST=unit_test, browser_tests: *FileSystemProvider*Writable*
BUG=391362

Review URL: https://codereview.chromium.org/372163006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@282890 0039d316-1c4b-4281-b951-d872f2087c98
parent 2353067a
...@@ -52,7 +52,8 @@ bool FileSystemProviderMountFunction::RunSync() { ...@@ -52,7 +52,8 @@ bool FileSystemProviderMountFunction::RunSync() {
// TODO(mtomasz): Pass more detailed errors, rather than just a bool. // TODO(mtomasz): Pass more detailed errors, rather than just a bool.
if (!service->MountFileSystem(extension_id(), if (!service->MountFileSystem(extension_id(),
params->options.file_system_id, params->options.file_system_id,
params->options.display_name)) { params->options.display_name,
params->options.writable)) {
base::ListValue* result = new base::ListValue(); base::ListValue* result = new base::ListValue();
result->Append(CreateError(kSecurityErrorName, kMountFailedErrorMessage)); result->Append(CreateError(kSecurityErrorName, kMountFailedErrorMessage));
SetResult(result); SetResult(result);
......
...@@ -220,7 +220,7 @@ VolumeInfo CreateProvidedFileSystemVolumeInfo( ...@@ -220,7 +220,7 @@ VolumeInfo CreateProvidedFileSystemVolumeInfo(
volume_info.mount_path = file_system_info.mount_path(); volume_info.mount_path = file_system_info.mount_path();
volume_info.mount_condition = chromeos::disks::MOUNT_CONDITION_NONE; volume_info.mount_condition = chromeos::disks::MOUNT_CONDITION_NONE;
volume_info.is_parent = true; volume_info.is_parent = true;
volume_info.is_read_only = true; volume_info.is_read_only = !file_system_info.writable();
volume_info.volume_id = GenerateVolumeId(volume_info); volume_info.volume_id = GenerateVolumeId(volume_info);
return volume_info; return volume_info;
} }
......
...@@ -96,8 +96,10 @@ class FileSystemProviderFileStreamReader : public testing::Test { ...@@ -96,8 +96,10 @@ class FileSystemProviderFileStreamReader : public testing::Test {
service->SetFileSystemFactoryForTesting( service->SetFileSystemFactoryForTesting(
base::Bind(&FakeProvidedFileSystem::Create)); base::Bind(&FakeProvidedFileSystem::Create));
const bool result = service->MountFileSystem( const bool result = service->MountFileSystem(kExtensionId,
kExtensionId, kFileSystemId, "Testing File System"); kFileSystemId,
"Testing File System",
false /* writable */);
ASSERT_TRUE(result); ASSERT_TRUE(result);
const ProvidedFileSystemInfo& file_system_info = const ProvidedFileSystemInfo& file_system_info =
service->GetProvidedFileSystem(kExtensionId, kFileSystemId) service->GetProvidedFileSystem(kExtensionId, kFileSystemId)
......
...@@ -141,8 +141,10 @@ class FileSystemProviderProviderAsyncFileUtilTest : public testing::Test { ...@@ -141,8 +141,10 @@ class FileSystemProviderProviderAsyncFileUtilTest : public testing::Test {
service->SetFileSystemFactoryForTesting( service->SetFileSystemFactoryForTesting(
base::Bind(&FakeProvidedFileSystem::Create)); base::Bind(&FakeProvidedFileSystem::Create));
const bool result = service->MountFileSystem( const bool result = service->MountFileSystem(kExtensionId,
kExtensionId, kFileSystemId, "Testing File System"); kFileSystemId,
"Testing File System",
false /* writable */);
ASSERT_TRUE(result); ASSERT_TRUE(result);
const ProvidedFileSystemInfo& file_system_info = const ProvidedFileSystemInfo& file_system_info =
service->GetProvidedFileSystem(kExtensionId, kFileSystemId) service->GetProvidedFileSystem(kExtensionId, kFileSystemId)
......
...@@ -127,7 +127,7 @@ TEST_F(FileSystemProviderMountPathUtilTest, IsFileSystemProviderLocalPath) { ...@@ -127,7 +127,7 @@ TEST_F(FileSystemProviderMountPathUtilTest, IsFileSystemProviderLocalPath) {
TEST_F(FileSystemProviderMountPathUtilTest, Parser) { TEST_F(FileSystemProviderMountPathUtilTest, Parser) {
const bool result = file_system_provider_service_->MountFileSystem( const bool result = file_system_provider_service_->MountFileSystem(
kExtensionId, kFileSystemId, kDisplayName); kExtensionId, kFileSystemId, kDisplayName, false /* writable */);
ASSERT_TRUE(result); ASSERT_TRUE(result);
const ProvidedFileSystemInfo file_system_info = const ProvidedFileSystemInfo file_system_info =
file_system_provider_service_->GetProvidedFileSystem(kExtensionId, file_system_provider_service_->GetProvidedFileSystem(kExtensionId,
...@@ -151,7 +151,7 @@ TEST_F(FileSystemProviderMountPathUtilTest, Parser) { ...@@ -151,7 +151,7 @@ TEST_F(FileSystemProviderMountPathUtilTest, Parser) {
TEST_F(FileSystemProviderMountPathUtilTest, Parser_RootPath) { TEST_F(FileSystemProviderMountPathUtilTest, Parser_RootPath) {
const bool result = file_system_provider_service_->MountFileSystem( const bool result = file_system_provider_service_->MountFileSystem(
kExtensionId, kFileSystemId, kDisplayName); kExtensionId, kFileSystemId, kDisplayName, false /* writable */);
ASSERT_TRUE(result); ASSERT_TRUE(result);
const ProvidedFileSystemInfo file_system_info = const ProvidedFileSystemInfo file_system_info =
file_system_provider_service_->GetProvidedFileSystem(kExtensionId, file_system_provider_service_->GetProvidedFileSystem(kExtensionId,
...@@ -177,6 +177,7 @@ TEST_F(FileSystemProviderMountPathUtilTest, Parser_WrongUrl) { ...@@ -177,6 +177,7 @@ TEST_F(FileSystemProviderMountPathUtilTest, Parser_WrongUrl) {
kExtensionId, kExtensionId,
kFileSystemId, kFileSystemId,
kDisplayName, kDisplayName,
false /* writable */,
GetMountPath(profile_, kExtensionId, kFileSystemId)); GetMountPath(profile_, kExtensionId, kFileSystemId));
const base::FilePath kFilePath = base::FilePath::FromUTF8Unsafe("/hello"); const base::FilePath kFilePath = base::FilePath::FromUTF8Unsafe("/hello");
...@@ -192,7 +193,7 @@ TEST_F(FileSystemProviderMountPathUtilTest, Parser_WrongUrl) { ...@@ -192,7 +193,7 @@ TEST_F(FileSystemProviderMountPathUtilTest, Parser_WrongUrl) {
TEST_F(FileSystemProviderMountPathUtilTest, Parser_IsolatedURL) { TEST_F(FileSystemProviderMountPathUtilTest, Parser_IsolatedURL) {
const bool result = file_system_provider_service_->MountFileSystem( const bool result = file_system_provider_service_->MountFileSystem(
kExtensionId, kFileSystemId, kDisplayName); kExtensionId, kFileSystemId, kDisplayName, false /* writable */);
ASSERT_TRUE(result); ASSERT_TRUE(result);
const ProvidedFileSystemInfo file_system_info = const ProvidedFileSystemInfo file_system_info =
file_system_provider_service_->GetProvidedFileSystem(kExtensionId, file_system_provider_service_->GetProvidedFileSystem(kExtensionId,
...@@ -238,7 +239,7 @@ TEST_F(FileSystemProviderMountPathUtilTest, Parser_IsolatedURL) { ...@@ -238,7 +239,7 @@ TEST_F(FileSystemProviderMountPathUtilTest, Parser_IsolatedURL) {
TEST_F(FileSystemProviderMountPathUtilTest, LocalPathParser) { TEST_F(FileSystemProviderMountPathUtilTest, LocalPathParser) {
const bool result = file_system_provider_service_->MountFileSystem( const bool result = file_system_provider_service_->MountFileSystem(
kExtensionId, kFileSystemId, kDisplayName); kExtensionId, kFileSystemId, kDisplayName, false /* writable */);
ASSERT_TRUE(result); ASSERT_TRUE(result);
const ProvidedFileSystemInfo file_system_info = const ProvidedFileSystemInfo file_system_info =
file_system_provider_service_->GetProvidedFileSystem(kExtensionId, file_system_provider_service_->GetProvidedFileSystem(kExtensionId,
...@@ -262,7 +263,7 @@ TEST_F(FileSystemProviderMountPathUtilTest, LocalPathParser) { ...@@ -262,7 +263,7 @@ TEST_F(FileSystemProviderMountPathUtilTest, LocalPathParser) {
TEST_F(FileSystemProviderMountPathUtilTest, LocalPathParser_RootPath) { TEST_F(FileSystemProviderMountPathUtilTest, LocalPathParser_RootPath) {
const bool result = file_system_provider_service_->MountFileSystem( const bool result = file_system_provider_service_->MountFileSystem(
kExtensionId, kFileSystemId, kDisplayName); kExtensionId, kFileSystemId, kDisplayName, false /* writable */);
ASSERT_TRUE(result); ASSERT_TRUE(result);
const ProvidedFileSystemInfo file_system_info = const ProvidedFileSystemInfo file_system_info =
file_system_provider_service_->GetProvidedFileSystem(kExtensionId, file_system_provider_service_->GetProvidedFileSystem(kExtensionId,
......
...@@ -40,6 +40,7 @@ class FileSystemProviderOperationsCloseFileTest : public testing::Test { ...@@ -40,6 +40,7 @@ class FileSystemProviderOperationsCloseFileTest : public testing::Test {
ProvidedFileSystemInfo(kExtensionId, ProvidedFileSystemInfo(kExtensionId,
kFileSystemId, kFileSystemId,
"" /* display_name */, "" /* display_name */,
false /* writable */,
base::FilePath() /* mount_path */); base::FilePath() /* mount_path */);
} }
......
...@@ -40,6 +40,7 @@ class FileSystemProviderOperationsCreateDirectoryTest : public testing::Test { ...@@ -40,6 +40,7 @@ class FileSystemProviderOperationsCreateDirectoryTest : public testing::Test {
ProvidedFileSystemInfo(kExtensionId, ProvidedFileSystemInfo(kExtensionId,
kFileSystemId, kFileSystemId,
"" /* file_system_name */, "" /* file_system_name */,
true /* writable */,
base::FilePath() /* mount_path */); base::FilePath() /* mount_path */);
} }
......
...@@ -40,6 +40,7 @@ class FileSystemProviderOperationsDeleteEntryTest : public testing::Test { ...@@ -40,6 +40,7 @@ class FileSystemProviderOperationsDeleteEntryTest : public testing::Test {
ProvidedFileSystemInfo(kExtensionId, ProvidedFileSystemInfo(kExtensionId,
kFileSystemId, kFileSystemId,
"" /* file_system_name */, "" /* file_system_name */,
false /* writable */,
base::FilePath() /* mount_path */); base::FilePath() /* mount_path */);
} }
......
...@@ -77,6 +77,7 @@ class FileSystemProviderOperationsGetMetadataTest : public testing::Test { ...@@ -77,6 +77,7 @@ class FileSystemProviderOperationsGetMetadataTest : public testing::Test {
ProvidedFileSystemInfo(kExtensionId, ProvidedFileSystemInfo(kExtensionId,
kFileSystemId, kFileSystemId,
"" /* display_name */, "" /* display_name */,
false /* writable */,
base::FilePath() /* mount_path */); base::FilePath() /* mount_path */);
} }
......
...@@ -76,6 +76,7 @@ class FileSystemProviderOperationsOpenFileTest : public testing::Test { ...@@ -76,6 +76,7 @@ class FileSystemProviderOperationsOpenFileTest : public testing::Test {
ProvidedFileSystemInfo(kExtensionId, ProvidedFileSystemInfo(kExtensionId,
kFileSystemId, kFileSystemId,
"" /* display_name */, "" /* display_name */,
false /* writable */,
base::FilePath() /* mount_path */); base::FilePath() /* mount_path */);
} }
......
...@@ -84,6 +84,7 @@ class FileSystemProviderOperationsReadDirectoryTest : public testing::Test { ...@@ -84,6 +84,7 @@ class FileSystemProviderOperationsReadDirectoryTest : public testing::Test {
ProvidedFileSystemInfo(kExtensionId, ProvidedFileSystemInfo(kExtensionId,
kFileSystemId, kFileSystemId,
"" /* display_name */, "" /* display_name */,
false /* writable */,
base::FilePath() /* mount_path */); base::FilePath() /* mount_path */);
} }
......
...@@ -81,6 +81,7 @@ class FileSystemProviderOperationsReadFileTest : public testing::Test { ...@@ -81,6 +81,7 @@ class FileSystemProviderOperationsReadFileTest : public testing::Test {
ProvidedFileSystemInfo(kExtensionId, ProvidedFileSystemInfo(kExtensionId,
kFileSystemId, kFileSystemId,
"" /* display_name */, "" /* display_name */,
false /* writable */,
base::FilePath() /* mount_path */); base::FilePath() /* mount_path */);
io_buffer_ = make_scoped_refptr(new net::IOBuffer(kOffset + kLength)); io_buffer_ = make_scoped_refptr(new net::IOBuffer(kOffset + kLength));
} }
......
...@@ -38,6 +38,7 @@ class FileSystemProviderOperationsUnmountTest : public testing::Test { ...@@ -38,6 +38,7 @@ class FileSystemProviderOperationsUnmountTest : public testing::Test {
ProvidedFileSystemInfo(kExtensionId, ProvidedFileSystemInfo(kExtensionId,
kFileSystemId, kFileSystemId,
"" /* display_name */, "" /* display_name */,
false /* writable */,
base::FilePath() /* mount_path */); base::FilePath() /* mount_path */);
} }
......
...@@ -13,10 +13,12 @@ ProvidedFileSystemInfo::ProvidedFileSystemInfo( ...@@ -13,10 +13,12 @@ ProvidedFileSystemInfo::ProvidedFileSystemInfo(
const std::string& extension_id, const std::string& extension_id,
const std::string& file_system_id, const std::string& file_system_id,
const std::string& display_name, const std::string& display_name,
bool writable,
const base::FilePath& mount_path) const base::FilePath& mount_path)
: extension_id_(extension_id), : extension_id_(extension_id),
file_system_id_(file_system_id), file_system_id_(file_system_id),
display_name_(display_name), display_name_(display_name),
writable_(writable),
mount_path_(mount_path) { mount_path_(mount_path) {
} }
......
...@@ -19,6 +19,7 @@ class ProvidedFileSystemInfo { ...@@ -19,6 +19,7 @@ class ProvidedFileSystemInfo {
ProvidedFileSystemInfo(const std::string& extension_id, ProvidedFileSystemInfo(const std::string& extension_id,
const std::string& file_system_id, const std::string& file_system_id,
const std::string& display_name, const std::string& display_name,
const bool writable,
const base::FilePath& mount_path); const base::FilePath& mount_path);
~ProvidedFileSystemInfo(); ~ProvidedFileSystemInfo();
...@@ -26,6 +27,7 @@ class ProvidedFileSystemInfo { ...@@ -26,6 +27,7 @@ class ProvidedFileSystemInfo {
const std::string& extension_id() const { return extension_id_; } const std::string& extension_id() const { return extension_id_; }
const std::string& file_system_id() const { return file_system_id_; } const std::string& file_system_id() const { return file_system_id_; }
const std::string& display_name() const { return display_name_; } const std::string& display_name() const { return display_name_; }
bool writable() const { return writable_; }
const base::FilePath& mount_path() const { return mount_path_; } const base::FilePath& mount_path() const { return mount_path_; }
private: private:
...@@ -38,6 +40,9 @@ class ProvidedFileSystemInfo { ...@@ -38,6 +40,9 @@ class ProvidedFileSystemInfo {
// Name of the file system, can be rendered in the UI. // Name of the file system, can be rendered in the UI.
std::string display_name_; std::string display_name_;
// Whether the file system is writable or just read-only.
bool writable_;
// Mount path of the underlying file system. // Mount path of the underlying file system.
base::FilePath mount_path_; base::FilePath mount_path_;
}; };
......
...@@ -39,6 +39,7 @@ ProvidedFileSystemInterface* CreateProvidedFileSystem( ...@@ -39,6 +39,7 @@ ProvidedFileSystemInterface* CreateProvidedFileSystem(
const char kPrefKeyFileSystemId[] = "file-system-id"; const char kPrefKeyFileSystemId[] = "file-system-id";
const char kPrefKeyDisplayName[] = "display-name"; const char kPrefKeyDisplayName[] = "display-name";
const char kPrefKeyWritable[] = "writable";
void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) { void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
registry->RegisterDictionaryPref( registry->RegisterDictionaryPref(
...@@ -101,7 +102,8 @@ void Service::SetFileSystemFactoryForTesting( ...@@ -101,7 +102,8 @@ void Service::SetFileSystemFactoryForTesting(
bool Service::MountFileSystem(const std::string& extension_id, bool Service::MountFileSystem(const std::string& extension_id,
const std::string& file_system_id, const std::string& file_system_id,
const std::string& display_name) { const std::string& display_name,
bool writable) {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
// If already exists a file system provided by the same extension with this // If already exists a file system provided by the same extension with this
...@@ -149,11 +151,12 @@ bool Service::MountFileSystem(const std::string& extension_id, ...@@ -149,11 +151,12 @@ bool Service::MountFileSystem(const std::string& extension_id,
// Store the file system descriptor. Use the mount point name as the file // Store the file system descriptor. Use the mount point name as the file
// system provider file system id. // system provider file system id.
// Examples: // Examples:
// file_system_id = 41 // file_system_id = hello_world
// mount_point_name = b33f1337-41-5aa5 // mount_point_name = b33f1337-hello_world-5aa5
// mount_path = /provided/b33f1337-41-5aa5 // writable = false
// mount_path = /provided/b33f1337-hello_world-5aa5
ProvidedFileSystemInfo file_system_info( ProvidedFileSystemInfo file_system_info(
extension_id, file_system_id, display_name, mount_path); extension_id, file_system_id, display_name, writable, mount_path);
ProvidedFileSystemInterface* file_system = ProvidedFileSystemInterface* file_system =
file_system_factory_.Run(profile_, file_system_info); file_system_factory_.Run(profile_, file_system_info);
...@@ -331,6 +334,8 @@ void Service::RememberFileSystem( ...@@ -331,6 +334,8 @@ void Service::RememberFileSystem(
file_system_info.file_system_id()); file_system_info.file_system_id());
file_system->SetStringWithoutPathExpansion(kPrefKeyDisplayName, file_system->SetStringWithoutPathExpansion(kPrefKeyDisplayName,
file_system_info.display_name()); file_system_info.display_name());
file_system->SetBooleanWithoutPathExpansion(kPrefKeyWritable,
file_system_info.writable());
PrefService* const pref_service = profile_->GetPrefs(); PrefService* const pref_service = profile_->GetPrefs();
DCHECK(pref_service); DCHECK(pref_service);
...@@ -397,21 +402,23 @@ void Service::RestoreFileSystems(const std::string& extension_id) { ...@@ -397,21 +402,23 @@ void Service::RestoreFileSystems(const std::string& extension_id) {
std::string file_system_id; std::string file_system_id;
std::string display_name; std::string display_name;
if (file_system_value->GetAsDictionary(&file_system)) { bool writable;
file_system->GetStringWithoutPathExpansion(kPrefKeyFileSystemId,
&file_system_id); if (!file_system_value->GetAsDictionary(&file_system) ||
file_system->GetStringWithoutPathExpansion(kPrefKeyDisplayName, !file_system->GetStringWithoutPathExpansion(kPrefKeyFileSystemId,
&display_name); &file_system_id) ||
} !file_system->GetStringWithoutPathExpansion(kPrefKeyDisplayName,
&display_name) ||
if (file_system_id.empty() || display_name.empty()) { !file_system->GetBooleanWithoutPathExpansion(kPrefKeyWritable,
&writable) ||
file_system_id.empty() || display_name.empty()) {
LOG(ERROR) LOG(ERROR)
<< "Malformed provided file system information in preferences."; << "Malformed provided file system information in preferences.";
continue; continue;
} }
const bool result = const bool result =
MountFileSystem(extension_id, file_system_id, display_name); MountFileSystem(extension_id, file_system_id, display_name, writable);
if (!result) { if (!result) {
LOG(ERROR) << "Failed to restore a provided file system from " LOG(ERROR) << "Failed to restore a provided file system from "
<< "preferences: " << extension_id << ", " << file_system_id << "preferences: " << extension_id << ", " << file_system_id
......
...@@ -39,6 +39,7 @@ namespace file_system_provider { ...@@ -39,6 +39,7 @@ namespace file_system_provider {
// Key names for preferences. // Key names for preferences.
extern const char kPrefKeyFileSystemId[]; extern const char kPrefKeyFileSystemId[];
extern const char kPrefKeyDisplayName[]; extern const char kPrefKeyDisplayName[];
extern const char kPrefKeyWritable[];
class ProvidedFileSystemFactoryInterface; class ProvidedFileSystemFactoryInterface;
class ProvidedFileSystemInfo; class ProvidedFileSystemInfo;
...@@ -71,11 +72,14 @@ class Service : public KeyedService, ...@@ -71,11 +72,14 @@ class Service : public KeyedService,
void SetFileSystemFactoryForTesting( void SetFileSystemFactoryForTesting(
const FileSystemFactoryCallback& factory_callback); const FileSystemFactoryCallback& factory_callback);
// Mounts a file system provided by an extension with the |extension_id|. // Mounts a file system provided by an extension with the |extension_id|. If
// For success, returns true, otherwise false. // |writable| is set to true, then the file system is mounted in a R/W mode.
// Otherwise, only read-only operations are supported. For success, returns
// true, otherwise false.
bool MountFileSystem(const std::string& extension_id, bool MountFileSystem(const std::string& extension_id,
const std::string& file_system_id, const std::string& file_system_id,
const std::string& display_name); const std::string& display_name,
bool writable);
// Unmounts a file system with the specified |file_system_id| for the // Unmounts a file system with the specified |file_system_id| for the
// |extension_id|. For success returns true, otherwise false. // |extension_id|. For success returns true, otherwise false.
......
...@@ -100,7 +100,8 @@ scoped_refptr<extensions::Extension> createFakeExtension( ...@@ -100,7 +100,8 @@ scoped_refptr<extensions::Extension> createFakeExtension(
void RememberFakeFileSystem(TestingProfile* profile, void RememberFakeFileSystem(TestingProfile* profile,
const std::string& extension_id, const std::string& extension_id,
const std::string& file_system_id, const std::string& file_system_id,
const std::string& display_name) { const std::string& display_name,
bool writable) {
TestingPrefServiceSyncable* const pref_service = TestingPrefServiceSyncable* const pref_service =
profile->GetTestingPrefService(); profile->GetTestingPrefService();
ASSERT_TRUE(pref_service); ASSERT_TRUE(pref_service);
...@@ -111,6 +112,7 @@ void RememberFakeFileSystem(TestingProfile* profile, ...@@ -111,6 +112,7 @@ void RememberFakeFileSystem(TestingProfile* profile,
file_system->SetStringWithoutPathExpansion(kPrefKeyFileSystemId, file_system->SetStringWithoutPathExpansion(kPrefKeyFileSystemId,
kFileSystemId); kFileSystemId);
file_system->SetStringWithoutPathExpansion(kPrefKeyDisplayName, kDisplayName); file_system->SetStringWithoutPathExpansion(kPrefKeyDisplayName, kDisplayName);
file_system->SetBooleanWithoutPathExpansion(kPrefKeyWritable, writable);
file_systems->SetWithoutPathExpansion(kFileSystemId, file_system); file_systems->SetWithoutPathExpansion(kFileSystemId, file_system);
extensions.SetWithoutPathExpansion(kExtensionId, file_systems); extensions.SetWithoutPathExpansion(kExtensionId, file_systems);
...@@ -150,8 +152,8 @@ TEST_F(FileSystemProviderServiceTest, MountFileSystem) { ...@@ -150,8 +152,8 @@ TEST_F(FileSystemProviderServiceTest, MountFileSystem) {
LoggingObserver observer; LoggingObserver observer;
service_->AddObserver(&observer); service_->AddObserver(&observer);
EXPECT_TRUE( EXPECT_TRUE(service_->MountFileSystem(
service_->MountFileSystem(kExtensionId, kFileSystemId, kDisplayName)); kExtensionId, kFileSystemId, kDisplayName, false /* writable */));
ASSERT_EQ(1u, observer.mounts.size()); ASSERT_EQ(1u, observer.mounts.size());
EXPECT_EQ(kExtensionId, observer.mounts[0].file_system_info().extension_id()); EXPECT_EQ(kExtensionId, observer.mounts[0].file_system_info().extension_id());
...@@ -162,6 +164,7 @@ TEST_F(FileSystemProviderServiceTest, MountFileSystem) { ...@@ -162,6 +164,7 @@ TEST_F(FileSystemProviderServiceTest, MountFileSystem) {
EXPECT_EQ(expected_mount_path.AsUTF8Unsafe(), EXPECT_EQ(expected_mount_path.AsUTF8Unsafe(),
observer.mounts[0].file_system_info().mount_path().AsUTF8Unsafe()); observer.mounts[0].file_system_info().mount_path().AsUTF8Unsafe());
EXPECT_EQ(kDisplayName, observer.mounts[0].file_system_info().display_name()); EXPECT_EQ(kDisplayName, observer.mounts[0].file_system_info().display_name());
EXPECT_FALSE(observer.mounts[0].file_system_info().writable());
EXPECT_EQ(base::File::FILE_OK, observer.mounts[0].error()); EXPECT_EQ(base::File::FILE_OK, observer.mounts[0].error());
ASSERT_EQ(0u, observer.unmounts.size()); ASSERT_EQ(0u, observer.unmounts.size());
...@@ -172,14 +175,31 @@ TEST_F(FileSystemProviderServiceTest, MountFileSystem) { ...@@ -172,14 +175,31 @@ TEST_F(FileSystemProviderServiceTest, MountFileSystem) {
service_->RemoveObserver(&observer); service_->RemoveObserver(&observer);
} }
TEST_F(FileSystemProviderServiceTest, MountFileSystem_Writable) {
LoggingObserver observer;
service_->AddObserver(&observer);
EXPECT_TRUE(service_->MountFileSystem(
kExtensionId, kFileSystemId, kDisplayName, true /* writable */));
ASSERT_EQ(1u, observer.mounts.size());
EXPECT_TRUE(observer.mounts[0].file_system_info().writable());
ASSERT_EQ(0u, observer.unmounts.size());
std::vector<ProvidedFileSystemInfo> file_system_info_list =
service_->GetProvidedFileSystemInfoList();
ASSERT_EQ(1u, file_system_info_list.size());
service_->RemoveObserver(&observer);
}
TEST_F(FileSystemProviderServiceTest, MountFileSystem_UniqueIds) { TEST_F(FileSystemProviderServiceTest, MountFileSystem_UniqueIds) {
LoggingObserver observer; LoggingObserver observer;
service_->AddObserver(&observer); service_->AddObserver(&observer);
EXPECT_TRUE( EXPECT_TRUE(service_->MountFileSystem(
service_->MountFileSystem(kExtensionId, kFileSystemId, kDisplayName)); kExtensionId, kFileSystemId, kDisplayName, false /* writable */));
EXPECT_FALSE( EXPECT_FALSE(service_->MountFileSystem(
service_->MountFileSystem(kExtensionId, kFileSystemId, kDisplayName)); kExtensionId, kFileSystemId, kDisplayName, false /* writable */));
ASSERT_EQ(2u, observer.mounts.size()); ASSERT_EQ(2u, observer.mounts.size());
EXPECT_EQ(base::File::FILE_OK, observer.mounts[0].error()); EXPECT_EQ(base::File::FILE_OK, observer.mounts[0].error());
...@@ -200,14 +220,14 @@ TEST_F(FileSystemProviderServiceTest, MountFileSystem_StressTest) { ...@@ -200,14 +220,14 @@ TEST_F(FileSystemProviderServiceTest, MountFileSystem_StressTest) {
for (size_t i = 0; i < kMaxFileSystems; ++i) { for (size_t i = 0; i < kMaxFileSystems; ++i) {
const std::string file_system_id = const std::string file_system_id =
std::string("test-") + base::IntToString(i); std::string("test-") + base::IntToString(i);
EXPECT_TRUE( EXPECT_TRUE(service_->MountFileSystem(
service_->MountFileSystem(kExtensionId, file_system_id, kDisplayName)); kExtensionId, file_system_id, kDisplayName, false /* writable */));
} }
ASSERT_EQ(kMaxFileSystems, observer.mounts.size()); ASSERT_EQ(kMaxFileSystems, observer.mounts.size());
// The next file system is out of limit, and registering it should fail. // The next file system is out of limit, and registering it should fail.
EXPECT_FALSE( EXPECT_FALSE(service_->MountFileSystem(
service_->MountFileSystem(kExtensionId, kFileSystemId, kDisplayName)); kExtensionId, kFileSystemId, kDisplayName, false /* writable */));
ASSERT_EQ(kMaxFileSystems + 1, observer.mounts.size()); ASSERT_EQ(kMaxFileSystems + 1, observer.mounts.size());
EXPECT_EQ(base::File::FILE_ERROR_TOO_MANY_OPENED, EXPECT_EQ(base::File::FILE_ERROR_TOO_MANY_OPENED,
...@@ -224,8 +244,8 @@ TEST_F(FileSystemProviderServiceTest, UnmountFileSystem) { ...@@ -224,8 +244,8 @@ TEST_F(FileSystemProviderServiceTest, UnmountFileSystem) {
LoggingObserver observer; LoggingObserver observer;
service_->AddObserver(&observer); service_->AddObserver(&observer);
EXPECT_TRUE( EXPECT_TRUE(service_->MountFileSystem(
service_->MountFileSystem(kExtensionId, kFileSystemId, kDisplayName)); kExtensionId, kFileSystemId, kDisplayName, false /* writable */));
ASSERT_EQ(1u, observer.mounts.size()); ASSERT_EQ(1u, observer.mounts.size());
EXPECT_TRUE(service_->UnmountFileSystem( EXPECT_TRUE(service_->UnmountFileSystem(
...@@ -249,8 +269,8 @@ TEST_F(FileSystemProviderServiceTest, UnmountFileSystem_OnExtensionUnload) { ...@@ -249,8 +269,8 @@ TEST_F(FileSystemProviderServiceTest, UnmountFileSystem_OnExtensionUnload) {
LoggingObserver observer; LoggingObserver observer;
service_->AddObserver(&observer); service_->AddObserver(&observer);
EXPECT_TRUE( EXPECT_TRUE(service_->MountFileSystem(
service_->MountFileSystem(kExtensionId, kFileSystemId, kDisplayName)); kExtensionId, kFileSystemId, kDisplayName, false /* writable */));
ASSERT_EQ(1u, observer.mounts.size()); ASSERT_EQ(1u, observer.mounts.size());
// Directly call the observer's method. // Directly call the observer's method.
...@@ -280,8 +300,8 @@ TEST_F(FileSystemProviderServiceTest, UnmountFileSystem_WrongExtensionId) { ...@@ -280,8 +300,8 @@ TEST_F(FileSystemProviderServiceTest, UnmountFileSystem_WrongExtensionId) {
const std::string kWrongExtensionId = "helloworldhelloworldhelloworldhe"; const std::string kWrongExtensionId = "helloworldhelloworldhelloworldhe";
EXPECT_TRUE( EXPECT_TRUE(service_->MountFileSystem(
service_->MountFileSystem(kExtensionId, kFileSystemId, kDisplayName)); kExtensionId, kFileSystemId, kDisplayName, false /* writable */));
ASSERT_EQ(1u, observer.mounts.size()); ASSERT_EQ(1u, observer.mounts.size());
ASSERT_EQ(1u, service_->GetProvidedFileSystemInfoList().size()); ASSERT_EQ(1u, service_->GetProvidedFileSystemInfoList().size());
...@@ -300,8 +320,11 @@ TEST_F(FileSystemProviderServiceTest, UnmountFileSystem_WrongExtensionId) { ...@@ -300,8 +320,11 @@ TEST_F(FileSystemProviderServiceTest, UnmountFileSystem_WrongExtensionId) {
TEST_F(FileSystemProviderServiceTest, RestoreFileSystem_OnExtensionLoad) { TEST_F(FileSystemProviderServiceTest, RestoreFileSystem_OnExtensionLoad) {
// Create a fake entry in the preferences. // Create a fake entry in the preferences.
RememberFakeFileSystem( RememberFakeFileSystem(profile_.get(),
profile_.get(), kExtensionId, kFileSystemId, kDisplayName); kExtensionId,
kFileSystemId,
kDisplayName,
true /* writable */);
// Create a new service instance in order to load remembered file systems // Create a new service instance in order to load remembered file systems
// from preferences. // from preferences.
...@@ -324,6 +347,7 @@ TEST_F(FileSystemProviderServiceTest, RestoreFileSystem_OnExtensionLoad) { ...@@ -324,6 +347,7 @@ TEST_F(FileSystemProviderServiceTest, RestoreFileSystem_OnExtensionLoad) {
EXPECT_EQ(kExtensionId, observer.mounts[0].file_system_info().extension_id()); EXPECT_EQ(kExtensionId, observer.mounts[0].file_system_info().extension_id());
EXPECT_EQ(kFileSystemId, EXPECT_EQ(kFileSystemId,
observer.mounts[0].file_system_info().file_system_id()); observer.mounts[0].file_system_info().file_system_id());
EXPECT_TRUE(observer.mounts[0].file_system_info().writable());
std::vector<ProvidedFileSystemInfo> file_system_info_list = std::vector<ProvidedFileSystemInfo> file_system_info_list =
new_service->GetProvidedFileSystemInfoList(); new_service->GetProvidedFileSystemInfoList();
...@@ -336,8 +360,8 @@ TEST_F(FileSystemProviderServiceTest, RememberFileSystem_OnMount) { ...@@ -336,8 +360,8 @@ TEST_F(FileSystemProviderServiceTest, RememberFileSystem_OnMount) {
LoggingObserver observer; LoggingObserver observer;
service_->AddObserver(&observer); service_->AddObserver(&observer);
EXPECT_TRUE( EXPECT_TRUE(service_->MountFileSystem(
service_->MountFileSystem(kExtensionId, kFileSystemId, kDisplayName)); kExtensionId, kFileSystemId, kDisplayName, true /* writable */));
ASSERT_EQ(1u, observer.mounts.size()); ASSERT_EQ(1u, observer.mounts.size());
TestingPrefServiceSyncable* const pref_service = TestingPrefServiceSyncable* const pref_service =
...@@ -369,6 +393,11 @@ TEST_F(FileSystemProviderServiceTest, RememberFileSystem_OnMount) { ...@@ -369,6 +393,11 @@ TEST_F(FileSystemProviderServiceTest, RememberFileSystem_OnMount) {
&display_name)); &display_name));
EXPECT_EQ(kDisplayName, display_name); EXPECT_EQ(kDisplayName, display_name);
bool writable = false;
EXPECT_TRUE(
file_system->GetBooleanWithoutPathExpansion(kPrefKeyWritable, &writable));
EXPECT_TRUE(writable);
service_->RemoveObserver(&observer); service_->RemoveObserver(&observer);
} }
...@@ -381,8 +410,8 @@ TEST_F(FileSystemProviderServiceTest, RememberFileSystem_OnUnmountOnShutdown) { ...@@ -381,8 +410,8 @@ TEST_F(FileSystemProviderServiceTest, RememberFileSystem_OnUnmountOnShutdown) {
ASSERT_TRUE(pref_service); ASSERT_TRUE(pref_service);
{ {
EXPECT_TRUE( EXPECT_TRUE(service_->MountFileSystem(
service_->MountFileSystem(kExtensionId, kFileSystemId, kDisplayName)); kExtensionId, kFileSystemId, kDisplayName, false /* writable */));
ASSERT_EQ(1u, observer.mounts.size()); ASSERT_EQ(1u, observer.mounts.size());
const base::DictionaryValue* extensions = const base::DictionaryValue* extensions =
...@@ -421,8 +450,8 @@ TEST_F(FileSystemProviderServiceTest, RememberFileSystem_OnUnmountByUser) { ...@@ -421,8 +450,8 @@ TEST_F(FileSystemProviderServiceTest, RememberFileSystem_OnUnmountByUser) {
ASSERT_TRUE(pref_service); ASSERT_TRUE(pref_service);
{ {
EXPECT_TRUE( EXPECT_TRUE(service_->MountFileSystem(
service_->MountFileSystem(kExtensionId, kFileSystemId, kDisplayName)); kExtensionId, kFileSystemId, kDisplayName, false /* writable */));
ASSERT_EQ(1u, observer.mounts.size()); ASSERT_EQ(1u, observer.mounts.size());
const base::DictionaryValue* extensions = const base::DictionaryValue* extensions =
......
...@@ -57,6 +57,7 @@ namespace fileSystemProvider { ...@@ -57,6 +57,7 @@ namespace fileSystemProvider {
dictionary MountOptions { dictionary MountOptions {
DOMString fileSystemId; DOMString fileSystemId;
DOMString displayName; DOMString displayName;
[nodoc] boolean? writable;
}; };
// Options for the <code>unmount()</code> method. // Options for the <code>unmount()</code> method.
......
...@@ -34,6 +34,7 @@ chrome.test.runTests([ ...@@ -34,6 +34,7 @@ chrome.test.runTests([
onTestSuccess(); onTestSuccess();
}); });
}, },
// Verifies that mounting fails, when an empty string is provided as an Id // Verifies that mounting fails, when an empty string is provided as an Id
function emptyFileSystemId() { function emptyFileSystemId() {
var onTestSuccess = chrome.test.callbackPass(); var onTestSuccess = chrome.test.callbackPass();
...@@ -59,14 +60,45 @@ chrome.test.runTests([ ...@@ -59,14 +60,45 @@ chrome.test.runTests([
{fileSystemId: fileSystemId, displayName: 'caramel-candy.zip'}, {fileSystemId: fileSystemId, displayName: 'caramel-candy.zip'},
function() { function() {
chrome.fileBrowserPrivate.getVolumeMetadataList(function(volumeList) { chrome.fileBrowserPrivate.getVolumeMetadataList(function(volumeList) {
var found = false; var volumeInfo;
volumeList.forEach(function(volumeInfo) { volumeList.forEach(function(inVolumeInfo) {
if (volumeInfo.extensionId == chrome.runtime.id && if (inVolumeInfo.extensionId == chrome.runtime.id &&
volumeInfo.fileSystemId == fileSystemId) { inVolumeInfo.fileSystemId == fileSystemId) {
found = true; volumeInfo = inVolumeInfo;
}
});
chrome.test.assertTrue(!!volumeInfo);
chrome.test.assertTrue(volumeInfo.isReadOnly);
onTestSuccess();
});
},
function(error) {
chrome.test.fail();
});
},
// Checks whether mounting a file system in writable mode ends up on filling
// out the volume info properly.
function successfulWritableMount() {
var onTestSuccess = chrome.test.callbackPass();
var fileSystemId = 'caramel-fudges';
chrome.fileSystemProvider.mount(
{
fileSystemId: fileSystemId,
displayName: 'caramel-fudges.zip',
writable: true
},
function() {
chrome.fileBrowserPrivate.getVolumeMetadataList(function(volumeList) {
var volumeInfo;
volumeList.forEach(function(inVolumeInfo) {
if (inVolumeInfo.extensionId == chrome.runtime.id &&
inVolumeInfo.fileSystemId == fileSystemId) {
volumeInfo = inVolumeInfo;
} }
}); });
chrome.test.assertTrue(found); chrome.test.assertTrue(!!volumeInfo);
chrome.test.assertFalse(volumeInfo.isReadOnly);
onTestSuccess(); onTestSuccess();
}); });
}, },
...@@ -81,7 +113,7 @@ chrome.test.runTests([ ...@@ -81,7 +113,7 @@ chrome.test.runTests([
// security error. // security error.
function stressMountTest() { function stressMountTest() {
var onTestSuccess = chrome.test.callbackPass(); var onTestSuccess = chrome.test.callbackPass();
var ALREADY_MOUNTED_FILE_SYSTEMS = 2; // By previous tests. var ALREADY_MOUNTED_FILE_SYSTEMS = 3; // By previous tests.
var MAX_FILE_SYSTEMS = 16; var MAX_FILE_SYSTEMS = 16;
var index = 0; var index = 0;
var tryNextOne = function() { var tryNextOne = function() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment