#include "chrome/browser/chromeos/file_system_provider/service.h"
#include "chrome/common/extensions/api/file_system_provider.h"
#include "chrome/common/extensions/api/file_system_provider_internal.h"
+#include "storage/browser/fileapi/watcher_manager.h"
+using chromeos::file_system_provider::MountOptions;
using chromeos::file_system_provider::ProvidedFileSystemInfo;
using chromeos::file_system_provider::ProvidedFileSystemInterface;
+using chromeos::file_system_provider::ProvidedFileSystemObserver;
using chromeos::file_system_provider::RequestValue;
using chromeos::file_system_provider::Service;
namespace extensions {
+namespace {
+
+typedef std::vector<linked_ptr<api::file_system_provider::Change>> IDLChanges;
+
+// Converts the change type from the IDL type to a native type. |changed_type|
+// must be specified (not CHANGE_TYPE_NONE).
+storage::WatcherManager::ChangeType ParseChangeType(
+ const api::file_system_provider::ChangeType& change_type) {
+ switch (change_type) {
+ case api::file_system_provider::CHANGE_TYPE_CHANGED:
+ return storage::WatcherManager::CHANGED;
+ case api::file_system_provider::CHANGE_TYPE_DELETED:
+ return storage::WatcherManager::DELETED;
+ default:
+ break;
+ }
+ NOTREACHED();
+ return storage::WatcherManager::CHANGED;
+}
+
+// Convert the change from the IDL type to a native type. The reason IDL types
+// are not used is since they are imperfect, eg. paths are stored as strings.
+ProvidedFileSystemObserver::Change ParseChange(
+ const api::file_system_provider::Change& change) {
+ ProvidedFileSystemObserver::Change result;
+ result.entry_path = base::FilePath::FromUTF8Unsafe(change.entry_path);
+ result.change_type = ParseChangeType(change.change_type);
+ return result;
+}
+
+// Converts a list of child changes from the IDL type to a native type.
+scoped_ptr<ProvidedFileSystemObserver::Changes> ParseChanges(
+ const IDLChanges& changes) {
+ scoped_ptr<ProvidedFileSystemObserver::Changes> results(
+ new ProvidedFileSystemObserver::Changes);
+ for (const auto& change : changes) {
+ results->push_back(ParseChange(*change));
+ }
+ return results;
+}
+
+} // namespace
bool FileSystemProviderMountFunction::RunSync() {
using api::file_system_provider::Mount::Params;
// It's an error if the file system Id is empty.
if (params->options.file_system_id.empty()) {
- base::ListValue* const result = new base::ListValue();
- result->Append(CreateError(kSecurityErrorName, kEmptyIdErrorMessage));
- SetResult(result);
- return true;
+ SetError(FileErrorToString(base::File::FILE_ERROR_SECURITY));
+ return false;
}
// It's an error if the display name is empty.
if (params->options.display_name.empty()) {
- base::ListValue* const result = new base::ListValue();
- result->Append(CreateError(kSecurityErrorName,
- kEmptyNameErrorMessage));
- SetResult(result);
- return true;
+ SetError(FileErrorToString(base::File::FILE_ERROR_SECURITY));
+ return false;
}
Service* const service = Service::Get(GetProfile());
DCHECK(service);
- if (!service)
- return false;
+
+ MountOptions options;
+ options.file_system_id = params->options.file_system_id;
+ options.display_name = params->options.display_name;
+ options.writable = params->options.writable;
+ options.supports_notify_tag = params->options.supports_notify_tag;
// TODO(mtomasz): Pass more detailed errors, rather than just a bool.
- if (!service->MountFileSystem(extension_id(),
- params->options.file_system_id,
- params->options.display_name,
- params->options.writable)) {
- base::ListValue* const result = new base::ListValue();
- result->Append(CreateError(kSecurityErrorName, kMountFailedErrorMessage));
- SetResult(result);
- return true;
+ if (!service->MountFileSystem(extension_id(), options)) {
+ SetError(FileErrorToString(base::File::FILE_ERROR_SECURITY));
+ return false;
}
- base::ListValue* result = new base::ListValue();
- SetResult(result);
return true;
}
Service* const service = Service::Get(GetProfile());
DCHECK(service);
- if (!service)
- return false;
if (!service->UnmountFileSystem(extension_id(),
params->options.file_system_id,
Service::UNMOUNT_REASON_USER)) {
// TODO(mtomasz): Pass more detailed errors, rather than just a bool.
- base::ListValue* result = new base::ListValue();
- result->Append(CreateError(kSecurityErrorName, kUnmountFailedErrorMessage));
- SetResult(result);
- return true;
+ SetError(FileErrorToString(base::File::FILE_ERROR_SECURITY));
+ return false;
}
- base::ListValue* const result = new base::ListValue();
- SetResult(result);
return true;
}
bool FileSystemProviderGetAllFunction::RunSync() {
using api::file_system_provider::FileSystemInfo;
+ using api::file_system_provider::Watcher;
Service* const service = Service::Get(GetProfile());
DCHECK(service);
- if (!service)
- return false;
const std::vector<ProvidedFileSystemInfo> file_systems =
service->GetProvidedFileSystemInfoList();
- std::vector<linked_ptr<FileSystemInfo> > items;
-
- for (size_t i = 0; i < file_systems.size(); ++i) {
- linked_ptr<FileSystemInfo> item(new FileSystemInfo);
- item->file_system_id = file_systems[i].file_system_id();
- item->display_name = file_systems[i].display_name();
- item->writable = file_systems[i].writable();
- items.push_back(item);
+ std::vector<linked_ptr<FileSystemInfo>> items;
+
+ for (const auto& file_system_info : file_systems) {
+ if (file_system_info.extension_id() == extension_id()) {
+ const linked_ptr<FileSystemInfo> item(new FileSystemInfo);
+ item->file_system_id = file_system_info.file_system_id();
+ item->display_name = file_system_info.display_name();
+ item->writable = file_system_info.writable();
+
+ chromeos::file_system_provider::ProvidedFileSystemInterface* const
+ file_system =
+ service->GetProvidedFileSystem(file_system_info.extension_id(),
+ file_system_info.file_system_id());
+ DCHECK(file_system);
+
+ std::vector<linked_ptr<Watcher>> watcher_items;
+ chromeos::file_system_provider::Watchers* const watchers =
+ file_system->GetWatchers();
+ DCHECK(watchers);
+
+ for (const auto& watcher : *watchers) {
+ const linked_ptr<Watcher> watcher_item(new Watcher);
+ watcher_item->entry_path = watcher.second.entry_path.value();
+ watcher_item->recursive = watcher.second.recursive;
+ if (!watcher.second.last_tag.empty())
+ watcher_item->last_tag.reset(
+ new std::string(watcher.second.last_tag));
+ watcher_items.push_back(watcher_item);
+ }
+
+ item->watchers = watcher_items;
+ items.push_back(item);
+ }
}
SetResultList(api::file_system_provider::GetAll::Results::Create(items));
return true;
}
+bool FileSystemProviderNotifyFunction::RunSync() {
+ using api::file_system_provider::Notify::Params;
+ scoped_ptr<Params> params(Params::Create(*args_));
+ EXTENSION_FUNCTION_VALIDATE(params);
+
+ Service* const service = Service::Get(GetProfile());
+ DCHECK(service);
+
+ ProvidedFileSystemInterface* const file_system =
+ service->GetProvidedFileSystem(extension_id(),
+ params->options.file_system_id);
+ if (!file_system) {
+ SetError(FileErrorToString(base::File::FILE_ERROR_SECURITY));
+ return false;
+ }
+
+ if (!file_system->Notify(
+ base::FilePath::FromUTF8Unsafe(params->options.observed_path),
+ params->options.recursive,
+ ParseChangeType(params->options.change_type),
+ params->options.changes.get()
+ ? ParseChanges(*params->options.changes.get())
+ : make_scoped_ptr(new ProvidedFileSystemObserver::Changes),
+ params->options.tag.get() ? *params->options.tag.get() : "")) {
+ SetError(FileErrorToString(base::File::FILE_ERROR_SECURITY));
+ return false;
+ }
+
+ return true;
+}
+
bool FileSystemProviderInternalUnmountRequestedSuccessFunction::RunWhenValid() {
using api::file_system_provider_internal::UnmountRequestedSuccess::Params;
scoped_ptr<Params> params(Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params);
- FulfillRequest(RequestValue::CreateForUnmountSuccess(params.Pass()),
- false /* has_more */);
- return true;
+ return FulfillRequest(RequestValue::CreateForUnmountSuccess(params.Pass()),
+ false /* has_more */);
}
bool
scoped_ptr<Params> params(Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params);
- FulfillRequest(RequestValue::CreateForGetMetadataSuccess(params.Pass()),
- false /* has_more */);
- return true;
+ return FulfillRequest(
+ RequestValue::CreateForGetMetadataSuccess(params.Pass()),
+ false /* has_more */);
}
bool FileSystemProviderInternalReadDirectoryRequestedSuccessFunction::
EXTENSION_FUNCTION_VALIDATE(params);
const bool has_more = params->has_more;
- FulfillRequest(RequestValue::CreateForReadDirectorySuccess(params.Pass()),
- has_more);
- return true;
+ return FulfillRequest(
+ RequestValue::CreateForReadDirectorySuccess(params.Pass()), has_more);
}
bool
EXTENSION_FUNCTION_VALIDATE(params);
const bool has_more = params->has_more;
- FulfillRequest(RequestValue::CreateForReadFileSuccess(params.Pass()),
- has_more);
- return true;
+ return FulfillRequest(RequestValue::CreateForReadFileSuccess(params.Pass()),
+ has_more);
}
bool
scoped_ptr<Params> params(Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params);
- FulfillRequest(scoped_ptr<RequestValue>(
- RequestValue::CreateForOperationSuccess(params.Pass())),
- false /* has_more */);
- return true;
+ return FulfillRequest(
+ scoped_ptr<RequestValue>(
+ RequestValue::CreateForOperationSuccess(params.Pass())),
+ false /* has_more */);
}
bool FileSystemProviderInternalOperationRequestedErrorFunction::RunWhenValid() {
EXTENSION_FUNCTION_VALIDATE(params);
const base::File::Error error = ProviderErrorToFileError(params->error);
- RejectRequest(RequestValue::CreateForOperationError(params.Pass()), error);
- return true;
+ return RejectRequest(RequestValue::CreateForOperationError(params.Pass()),
+ error);
}
} // namespace extensions