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.
4
5#include "chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_api.h"
6
7#include <string>
8#include <vector>
9
10#include "base/debug/trace_event.h"
11#include "base/memory/linked_ptr.h"
12#include "base/memory/scoped_ptr.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
21using chromeos::file_system_provider::ProvidedFileSystemInfo;
22using chromeos::file_system_provider::ProvidedFileSystemInterface;
23using chromeos::file_system_provider::RequestValue;
24using chromeos::file_system_provider::Service;
25
26namespace extensions {
27
28bool FileSystemProviderMountFunction::RunSync() {
29  using api::file_system_provider::Mount::Params;
30  const scoped_ptr<Params> params(Params::Create(*args_));
31  EXTENSION_FUNCTION_VALIDATE(params);
32
33  // It's an error if the file system Id is empty.
34  if (params->options.file_system_id.empty()) {
35    base::ListValue* const result = new base::ListValue();
36    result->Append(CreateError(kSecurityErrorName, kEmptyIdErrorMessage));
37    SetResult(result);
38    return true;
39  }
40
41  // It's an error if the display name is empty.
42  if (params->options.display_name.empty()) {
43    base::ListValue* const result = new base::ListValue();
44    result->Append(CreateError(kSecurityErrorName,
45                               kEmptyNameErrorMessage));
46    SetResult(result);
47    return true;
48  }
49
50  Service* const service = Service::Get(GetProfile());
51  DCHECK(service);
52  if (!service)
53    return false;
54
55  // TODO(mtomasz): Pass more detailed errors, rather than just a bool.
56  if (!service->MountFileSystem(extension_id(),
57                                params->options.file_system_id,
58                                params->options.display_name,
59                                params->options.writable)) {
60    base::ListValue* const result = new base::ListValue();
61    result->Append(CreateError(kSecurityErrorName, kMountFailedErrorMessage));
62    SetResult(result);
63    return true;
64  }
65
66  base::ListValue* result = new base::ListValue();
67  SetResult(result);
68  return true;
69}
70
71bool FileSystemProviderUnmountFunction::RunSync() {
72  using api::file_system_provider::Unmount::Params;
73  scoped_ptr<Params> params(Params::Create(*args_));
74  EXTENSION_FUNCTION_VALIDATE(params);
75
76  Service* const service = Service::Get(GetProfile());
77  DCHECK(service);
78  if (!service)
79    return false;
80
81  if (!service->UnmountFileSystem(extension_id(),
82                                  params->options.file_system_id,
83                                  Service::UNMOUNT_REASON_USER)) {
84    // TODO(mtomasz): Pass more detailed errors, rather than just a bool.
85    base::ListValue* result = new base::ListValue();
86    result->Append(CreateError(kSecurityErrorName, kUnmountFailedErrorMessage));
87    SetResult(result);
88    return true;
89  }
90
91  base::ListValue* const result = new base::ListValue();
92  SetResult(result);
93  return true;
94}
95
96bool FileSystemProviderGetAllFunction::RunSync() {
97  using api::file_system_provider::FileSystemInfo;
98  Service* const service = Service::Get(GetProfile());
99  DCHECK(service);
100  if (!service)
101    return false;
102
103  const std::vector<ProvidedFileSystemInfo> file_systems =
104      service->GetProvidedFileSystemInfoList();
105  std::vector<linked_ptr<FileSystemInfo> > items;
106
107  for (size_t i = 0; i < file_systems.size(); ++i) {
108    linked_ptr<FileSystemInfo> item(new FileSystemInfo);
109    item->file_system_id = file_systems[i].file_system_id();
110    item->display_name = file_systems[i].display_name();
111    item->writable = file_systems[i].writable();
112    items.push_back(item);
113  }
114
115  SetResultList(api::file_system_provider::GetAll::Results::Create(items));
116  return true;
117}
118
119bool FileSystemProviderInternalUnmountRequestedSuccessFunction::RunWhenValid() {
120  using api::file_system_provider_internal::UnmountRequestedSuccess::Params;
121  scoped_ptr<Params> params(Params::Create(*args_));
122  EXTENSION_FUNCTION_VALIDATE(params);
123
124  FulfillRequest(RequestValue::CreateForUnmountSuccess(params.Pass()),
125                 false /* has_more */);
126  return true;
127}
128
129bool
130FileSystemProviderInternalGetMetadataRequestedSuccessFunction::RunWhenValid() {
131  using api::file_system_provider_internal::GetMetadataRequestedSuccess::Params;
132  scoped_ptr<Params> params(Params::Create(*args_));
133  EXTENSION_FUNCTION_VALIDATE(params);
134
135  FulfillRequest(RequestValue::CreateForGetMetadataSuccess(params.Pass()),
136                 false /* has_more */);
137  return true;
138}
139
140bool FileSystemProviderInternalReadDirectoryRequestedSuccessFunction::
141    RunWhenValid() {
142  using api::file_system_provider_internal::ReadDirectoryRequestedSuccess::
143      Params;
144  scoped_ptr<Params> params(Params::Create(*args_));
145  EXTENSION_FUNCTION_VALIDATE(params);
146
147  const bool has_more = params->has_more;
148  FulfillRequest(RequestValue::CreateForReadDirectorySuccess(params.Pass()),
149                 has_more);
150  return true;
151}
152
153bool
154FileSystemProviderInternalReadFileRequestedSuccessFunction::RunWhenValid() {
155  TRACE_EVENT0("file_system_provider", "ReadFileRequestedSuccess");
156  using api::file_system_provider_internal::ReadFileRequestedSuccess::Params;
157
158  scoped_ptr<Params> params(Params::Create(*args_));
159  EXTENSION_FUNCTION_VALIDATE(params);
160
161  const bool has_more = params->has_more;
162  FulfillRequest(RequestValue::CreateForReadFileSuccess(params.Pass()),
163                 has_more);
164  return true;
165}
166
167bool
168FileSystemProviderInternalOperationRequestedSuccessFunction::RunWhenValid() {
169  using api::file_system_provider_internal::OperationRequestedSuccess::Params;
170  scoped_ptr<Params> params(Params::Create(*args_));
171  EXTENSION_FUNCTION_VALIDATE(params);
172
173  FulfillRequest(scoped_ptr<RequestValue>(
174                     RequestValue::CreateForOperationSuccess(params.Pass())),
175                 false /* has_more */);
176  return true;
177}
178
179bool FileSystemProviderInternalOperationRequestedErrorFunction::RunWhenValid() {
180  using api::file_system_provider_internal::OperationRequestedError::Params;
181  scoped_ptr<Params> params(Params::Create(*args_));
182  EXTENSION_FUNCTION_VALIDATE(params);
183
184  const base::File::Error error = ProviderErrorToFileError(params->error);
185  RejectRequest(RequestValue::CreateForOperationError(params.Pass()), error);
186  return true;
187}
188
189}  // namespace extensions
190