1010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// found in the LICENSE file.
4010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
5010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_api.h"
6010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
7010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h"
8010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/browser/chromeos/file_system_provider/request_manager.h"
9010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/browser/chromeos/file_system_provider/request_value.h"
10010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/browser/chromeos/file_system_provider/service.h"
11010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/common/extensions/api/file_system_provider_internal.h"
12010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
13010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)using chromeos::file_system_provider::ProvidedFileSystemInterface;
14010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)using chromeos::file_system_provider::RequestManager;
15010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)using chromeos::file_system_provider::RequestValue;
16010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)using chromeos::file_system_provider::Service;
17010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
18010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace extensions {
19010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
20010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kNotFoundErrorName[] = "NotFoundError";
21010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kSecurityErrorName[] = "SecurityError";
22010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
23010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kEmptyNameErrorMessage[] = "Empty display name is not allowed.";
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kEmptyIdErrorMessage[] = "Empty file system Id s not allowed.";
25010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kMountFailedErrorMessage[] = "Mounting the file system failed.";
26010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kUnmountFailedErrorMessage[] = "Unmounting the file system failed.";
27010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kResponseFailedErrorMessage[] =
28010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    "Sending a response for the request failed.";
29010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)base::DictionaryValue* CreateError(const std::string& name,
31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                   const std::string& message) {
32010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  base::DictionaryValue* error = new base::DictionaryValue();
33010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  error->SetString("name", name);
34010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  error->SetString("message", message);
35010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return error;
36010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
37010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)base::File::Error ProviderErrorToFileError(
39010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    api::file_system_provider::ProviderError error) {
40010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  switch (error) {
41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case api::file_system_provider::PROVIDER_ERROR_OK:
42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return base::File::FILE_OK;
43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case api::file_system_provider::PROVIDER_ERROR_FAILED:
44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return base::File::FILE_ERROR_FAILED;
45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case api::file_system_provider::PROVIDER_ERROR_IN_USE:
46010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return base::File::FILE_ERROR_IN_USE;
47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case api::file_system_provider::PROVIDER_ERROR_EXISTS:
48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return base::File::FILE_ERROR_EXISTS;
49010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case api::file_system_provider::PROVIDER_ERROR_NOT_FOUND:
50010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return base::File::FILE_ERROR_NOT_FOUND;
51010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case api::file_system_provider::PROVIDER_ERROR_ACCESS_DENIED:
52010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return base::File::FILE_ERROR_ACCESS_DENIED;
53010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case api::file_system_provider::PROVIDER_ERROR_TOO_MANY_OPENED:
54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return base::File::FILE_ERROR_TOO_MANY_OPENED;
55010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case api::file_system_provider::PROVIDER_ERROR_NO_MEMORY:
56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return base::File::FILE_ERROR_NO_MEMORY;
57010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case api::file_system_provider::PROVIDER_ERROR_NO_SPACE:
58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return base::File::FILE_ERROR_NO_SPACE;
59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case api::file_system_provider::PROVIDER_ERROR_NOT_A_DIRECTORY:
60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return base::File::FILE_ERROR_NOT_A_DIRECTORY;
61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case api::file_system_provider::PROVIDER_ERROR_INVALID_OPERATION:
62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return base::File::FILE_ERROR_INVALID_OPERATION;
63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case api::file_system_provider::PROVIDER_ERROR_SECURITY:
64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return base::File::FILE_ERROR_SECURITY;
65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case api::file_system_provider::PROVIDER_ERROR_NOT_A_FILE:
66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return base::File::FILE_ERROR_NOT_A_FILE;
67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case api::file_system_provider::PROVIDER_ERROR_NOT_EMPTY:
68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return base::File::FILE_ERROR_NOT_EMPTY;
69010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case api::file_system_provider::PROVIDER_ERROR_INVALID_URL:
70010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return base::File::FILE_ERROR_INVALID_URL;
71010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case api::file_system_provider::PROVIDER_ERROR_IO:
72010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      return base::File::FILE_ERROR_IO;
73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case api::file_system_provider::PROVIDER_ERROR_NONE:
74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      NOTREACHED();
75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
76010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return base::File::FILE_ERROR_FAILED;
77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)FileSystemProviderInternalFunction::FileSystemProviderInternalFunction()
80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    : request_id_(0), request_manager_(NULL) {
81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
82010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void FileSystemProviderInternalFunction::RejectRequest(
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    scoped_ptr<chromeos::file_system_provider::RequestValue> value,
85010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    base::File::Error error) {
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!request_manager_->RejectRequest(request_id_, value.Pass(), error))
87010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    SetErrorResponse(kSecurityErrorName, kResponseFailedErrorMessage);
88010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
89010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
90010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void FileSystemProviderInternalFunction::FulfillRequest(
91010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    scoped_ptr<RequestValue> value,
9246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    bool has_more) {
9346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!request_manager_->FulfillRequest(request_id_, value.Pass(), has_more))
94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    SetErrorResponse(kSecurityErrorName, kResponseFailedErrorMessage);
95010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
97010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool FileSystemProviderInternalFunction::RunSync() {
98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(args_);
99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!Parse())
100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return true;
101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  SendResponse(RunWhenValid());
103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return true;
104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
105010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
106010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool FileSystemProviderInternalFunction::Parse() {
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string file_system_id;
108010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!args_->GetString(0, &file_system_id) ||
110010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      !args_->GetInteger(1, &request_id_)) {
111010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    bad_message_ = true;
112010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    SendResponse(false);
113010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return false;
114010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
116010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  Service* service = Service::Get(GetProfile());
117010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!service) {
118010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    SendResponse(false);
119010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return false;
120010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ProvidedFileSystemInterface* file_system =
123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      service->GetProvidedFileSystem(extension_id(), file_system_id);
124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!file_system) {
125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    SetErrorResponse(kNotFoundErrorName, kResponseFailedErrorMessage);
126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    SendResponse(true);
127010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return false;
128010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
129010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
130010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  request_manager_ = file_system->GetRequestManager();
131010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return true;
132010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
133010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
134010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void FileSystemProviderInternalFunction::SetErrorResponse(
135010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const std::string& name,
136010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const std::string& message) {
137010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  base::ListValue* result = new base::ListValue();
138010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  result->Append(CreateError(name, message));
139010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  SetResult(result);
140010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
141010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
142010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}  // namespace extensions
143