ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / chrome / browser / chromeos / extensions / file_system_provider / file_system_provider_api.cc
blob09a892075b42b6b2db6226c4e2b4be81d3eef198
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_api.h"
7 #include <string>
8 #include <vector>
10 #include "base/memory/linked_ptr.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/trace_event/trace_event.h"
13 #include "base/values.h"
14 #include "chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h"
15 #include "chrome/browser/chromeos/file_system_provider/request_manager.h"
16 #include "chrome/browser/chromeos/file_system_provider/request_value.h"
17 #include "chrome/browser/chromeos/file_system_provider/service.h"
18 #include "chrome/common/extensions/api/file_system_provider.h"
19 #include "chrome/common/extensions/api/file_system_provider_internal.h"
20 #include "storage/browser/fileapi/watcher_manager.h"
22 using chromeos::file_system_provider::MountOptions;
23 using chromeos::file_system_provider::OpenedFiles;
24 using chromeos::file_system_provider::ProvidedFileSystemInfo;
25 using chromeos::file_system_provider::ProvidedFileSystemInterface;
26 using chromeos::file_system_provider::ProvidedFileSystemObserver;
27 using chromeos::file_system_provider::RequestValue;
28 using chromeos::file_system_provider::Service;
29 using chromeos::file_system_provider::Watchers;
31 namespace extensions {
32 namespace {
34 typedef std::vector<linked_ptr<api::file_system_provider::Change>> IDLChanges;
36 // Converts the change type from the IDL type to a native type. |changed_type|
37 // must be specified (not CHANGE_TYPE_NONE).
38 storage::WatcherManager::ChangeType ParseChangeType(
39 const api::file_system_provider::ChangeType& change_type) {
40 switch (change_type) {
41 case api::file_system_provider::CHANGE_TYPE_CHANGED:
42 return storage::WatcherManager::CHANGED;
43 case api::file_system_provider::CHANGE_TYPE_DELETED:
44 return storage::WatcherManager::DELETED;
45 default:
46 break;
48 NOTREACHED();
49 return storage::WatcherManager::CHANGED;
52 // Convert the change from the IDL type to a native type. The reason IDL types
53 // are not used is since they are imperfect, eg. paths are stored as strings.
54 ProvidedFileSystemObserver::Change ParseChange(
55 const api::file_system_provider::Change& change) {
56 ProvidedFileSystemObserver::Change result;
57 result.entry_path = base::FilePath::FromUTF8Unsafe(change.entry_path);
58 result.change_type = ParseChangeType(change.change_type);
59 return result;
62 // Converts a list of child changes from the IDL type to a native type.
63 scoped_ptr<ProvidedFileSystemObserver::Changes> ParseChanges(
64 const IDLChanges& changes) {
65 scoped_ptr<ProvidedFileSystemObserver::Changes> results(
66 new ProvidedFileSystemObserver::Changes);
67 for (const auto& change : changes) {
68 results->push_back(ParseChange(*change));
70 return results;
73 // Fills the IDL's FileSystemInfo with FSP's ProvidedFileSystemInfo and
74 // Watchers.
75 void FillFileSystemInfo(const ProvidedFileSystemInfo& file_system_info,
76 const Watchers& watchers,
77 const OpenedFiles& opened_files,
78 api::file_system_provider::FileSystemInfo* output) {
79 using api::file_system_provider::Watcher;
80 using api::file_system_provider::OpenedFile;
82 output->file_system_id = file_system_info.file_system_id();
83 output->display_name = file_system_info.display_name();
84 output->writable = file_system_info.writable();
85 output->opened_files_limit = file_system_info.opened_files_limit();
87 std::vector<linked_ptr<Watcher>> watcher_items;
88 for (const auto& watcher : watchers) {
89 const linked_ptr<Watcher> watcher_item(new Watcher);
90 watcher_item->entry_path = watcher.second.entry_path.value();
91 watcher_item->recursive = watcher.second.recursive;
92 if (!watcher.second.last_tag.empty())
93 watcher_item->last_tag.reset(new std::string(watcher.second.last_tag));
94 watcher_items.push_back(watcher_item);
96 output->watchers = watcher_items;
98 std::vector<linked_ptr<OpenedFile>> opened_file_items;
99 for (const auto& opened_file : opened_files) {
100 const linked_ptr<OpenedFile> opened_file_item(new OpenedFile);
101 opened_file_item->open_request_id = opened_file.first;
102 opened_file_item->file_path = opened_file.second.file_path.value();
103 switch (opened_file.second.mode) {
104 case chromeos::file_system_provider::OPEN_FILE_MODE_READ:
105 opened_file_item->mode =
106 extensions::api::file_system_provider::OPEN_FILE_MODE_READ;
107 break;
108 case chromeos::file_system_provider::OPEN_FILE_MODE_WRITE:
109 opened_file_item->mode =
110 extensions::api::file_system_provider::OPEN_FILE_MODE_WRITE;
111 break;
113 opened_file_items.push_back(opened_file_item);
115 output->opened_files = opened_file_items;
118 } // namespace
120 bool FileSystemProviderMountFunction::RunSync() {
121 using api::file_system_provider::Mount::Params;
122 const scoped_ptr<Params> params(Params::Create(*args_));
123 EXTENSION_FUNCTION_VALIDATE(params);
125 // It's an error if the file system Id is empty.
126 if (params->options.file_system_id.empty()) {
127 SetError(FileErrorToString(base::File::FILE_ERROR_INVALID_OPERATION));
128 return false;
131 // It's an error if the display name is empty.
132 if (params->options.display_name.empty()) {
133 SetError(FileErrorToString(base::File::FILE_ERROR_INVALID_OPERATION));
134 return false;
137 // If the opened files limit is set, then it must be larger or equal than 0.
138 if (params->options.opened_files_limit.get() &&
139 *params->options.opened_files_limit.get() < 0) {
140 SetError(FileErrorToString(base::File::FILE_ERROR_INVALID_OPERATION));
141 return false;
144 Service* const service = Service::Get(GetProfile());
145 DCHECK(service);
147 MountOptions options;
148 options.file_system_id = params->options.file_system_id;
149 options.display_name = params->options.display_name;
150 options.writable = params->options.writable;
151 options.opened_files_limit = params->options.opened_files_limit.get()
152 ? *params->options.opened_files_limit.get()
153 : 0;
154 options.supports_notify_tag = params->options.supports_notify_tag;
156 const base::File::Error result =
157 service->MountFileSystem(extension_id(), options);
158 if (result != base::File::FILE_OK) {
159 SetError(FileErrorToString(result));
160 return false;
163 return true;
166 bool FileSystemProviderUnmountFunction::RunSync() {
167 using api::file_system_provider::Unmount::Params;
168 scoped_ptr<Params> params(Params::Create(*args_));
169 EXTENSION_FUNCTION_VALIDATE(params);
171 Service* const service = Service::Get(GetProfile());
172 DCHECK(service);
174 const base::File::Error result =
175 service->UnmountFileSystem(extension_id(), params->options.file_system_id,
176 Service::UNMOUNT_REASON_USER);
177 if (result != base::File::FILE_OK) {
178 SetError(FileErrorToString(result));
179 return false;
182 return true;
185 bool FileSystemProviderGetAllFunction::RunSync() {
186 using api::file_system_provider::FileSystemInfo;
187 Service* const service = Service::Get(GetProfile());
188 DCHECK(service);
190 const std::vector<ProvidedFileSystemInfo> file_systems =
191 service->GetProvidedFileSystemInfoList();
192 std::vector<linked_ptr<FileSystemInfo>> items;
194 for (const auto& file_system_info : file_systems) {
195 if (file_system_info.extension_id() == extension_id()) {
196 const linked_ptr<FileSystemInfo> item(new FileSystemInfo);
198 chromeos::file_system_provider::ProvidedFileSystemInterface* const
199 file_system =
200 service->GetProvidedFileSystem(file_system_info.extension_id(),
201 file_system_info.file_system_id());
202 DCHECK(file_system);
204 FillFileSystemInfo(file_system_info, *file_system->GetWatchers(),
205 file_system->GetOpenedFiles(), item.get());
206 items.push_back(item);
210 SetResultList(api::file_system_provider::GetAll::Results::Create(items));
211 return true;
214 bool FileSystemProviderGetFunction::RunSync() {
215 using api::file_system_provider::Get::Params;
216 scoped_ptr<Params> params(Params::Create(*args_));
217 EXTENSION_FUNCTION_VALIDATE(params);
219 using api::file_system_provider::FileSystemInfo;
220 Service* const service = Service::Get(GetProfile());
221 DCHECK(service);
223 chromeos::file_system_provider::ProvidedFileSystemInterface* const
224 file_system = service->GetProvidedFileSystem(extension_id(),
225 params->file_system_id);
227 if (!file_system) {
228 SetError(FileErrorToString(base::File::FILE_ERROR_NOT_FOUND));
229 return false;
232 FileSystemInfo file_system_info;
233 FillFileSystemInfo(file_system->GetFileSystemInfo(),
234 *file_system->GetWatchers(), file_system->GetOpenedFiles(),
235 &file_system_info);
236 SetResultList(
237 api::file_system_provider::Get::Results::Create(file_system_info));
238 return true;
241 bool FileSystemProviderNotifyFunction::RunAsync() {
242 using api::file_system_provider::Notify::Params;
243 scoped_ptr<Params> params(Params::Create(*args_));
244 EXTENSION_FUNCTION_VALIDATE(params);
246 Service* const service = Service::Get(GetProfile());
247 DCHECK(service);
249 ProvidedFileSystemInterface* const file_system =
250 service->GetProvidedFileSystem(extension_id(),
251 params->options.file_system_id);
252 if (!file_system) {
253 SetError(FileErrorToString(base::File::FILE_ERROR_NOT_FOUND));
254 return false;
257 file_system->Notify(
258 base::FilePath::FromUTF8Unsafe(params->options.observed_path),
259 params->options.recursive, ParseChangeType(params->options.change_type),
260 params->options.changes.get()
261 ? ParseChanges(*params->options.changes.get())
262 : make_scoped_ptr(new ProvidedFileSystemObserver::Changes),
263 params->options.tag.get() ? *params->options.tag.get() : "",
264 base::Bind(&FileSystemProviderNotifyFunction::OnNotifyCompleted, this));
266 return true;
269 void FileSystemProviderNotifyFunction::OnNotifyCompleted(
270 base::File::Error result) {
271 if (result != base::File::FILE_OK) {
272 SetError(FileErrorToString(result));
273 SendResponse(false);
274 return;
277 SendResponse(true);
280 bool FileSystemProviderInternalUnmountRequestedSuccessFunction::RunWhenValid() {
281 using api::file_system_provider_internal::UnmountRequestedSuccess::Params;
282 scoped_ptr<Params> params(Params::Create(*args_));
283 EXTENSION_FUNCTION_VALIDATE(params);
285 return FulfillRequest(RequestValue::CreateForUnmountSuccess(params.Pass()),
286 false /* has_more */);
289 bool
290 FileSystemProviderInternalGetMetadataRequestedSuccessFunction::RunWhenValid() {
291 using api::file_system_provider_internal::GetMetadataRequestedSuccess::Params;
292 scoped_ptr<Params> params(Params::Create(*args_));
293 EXTENSION_FUNCTION_VALIDATE(params);
295 return FulfillRequest(
296 RequestValue::CreateForGetMetadataSuccess(params.Pass()),
297 false /* has_more */);
300 bool FileSystemProviderInternalReadDirectoryRequestedSuccessFunction::
301 RunWhenValid() {
302 using api::file_system_provider_internal::ReadDirectoryRequestedSuccess::
303 Params;
304 scoped_ptr<Params> params(Params::Create(*args_));
305 EXTENSION_FUNCTION_VALIDATE(params);
307 const bool has_more = params->has_more;
308 return FulfillRequest(
309 RequestValue::CreateForReadDirectorySuccess(params.Pass()), has_more);
312 bool
313 FileSystemProviderInternalReadFileRequestedSuccessFunction::RunWhenValid() {
314 TRACE_EVENT0("file_system_provider", "ReadFileRequestedSuccess");
315 using api::file_system_provider_internal::ReadFileRequestedSuccess::Params;
317 scoped_ptr<Params> params(Params::Create(*args_));
318 EXTENSION_FUNCTION_VALIDATE(params);
320 const bool has_more = params->has_more;
321 return FulfillRequest(RequestValue::CreateForReadFileSuccess(params.Pass()),
322 has_more);
325 bool
326 FileSystemProviderInternalOperationRequestedSuccessFunction::RunWhenValid() {
327 using api::file_system_provider_internal::OperationRequestedSuccess::Params;
328 scoped_ptr<Params> params(Params::Create(*args_));
329 EXTENSION_FUNCTION_VALIDATE(params);
331 return FulfillRequest(
332 scoped_ptr<RequestValue>(
333 RequestValue::CreateForOperationSuccess(params.Pass())),
334 false /* has_more */);
337 bool FileSystemProviderInternalOperationRequestedErrorFunction::RunWhenValid() {
338 using api::file_system_provider_internal::OperationRequestedError::Params;
339 scoped_ptr<Params> params(Params::Create(*args_));
340 EXTENSION_FUNCTION_VALIDATE(params);
342 const base::File::Error error = ProviderErrorToFileError(params->error);
343 return RejectRequest(RequestValue::CreateForOperationError(params.Pass()),
344 error);
347 } // namespace extensions