98e5c8f1a81a8368c83108fd2f798748a5f410b6
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / extensions / file_manager / private_api_util.cc
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_manager/private_api_util.h"
6
7 #include <string>
8
9 #include "base/files/file_path.h"
10 #include "base/message_loop/message_loop.h"
11 #include "chrome/browser/chromeos/drive/drive.pb.h"
12 #include "chrome/browser/chromeos/drive/file_errors.h"
13 #include "chrome/browser/chromeos/drive/file_system_interface.h"
14 #include "chrome/browser/chromeos/drive/file_system_util.h"
15 #include "chrome/browser/chromeos/file_manager/app_id.h"
16 #include "chrome/browser/chromeos/file_manager/fileapi_util.h"
17 #include "chrome/browser/chromeos/file_manager/volume_manager.h"
18 #include "chrome/browser/chromeos/fileapi/file_system_backend.h"
19 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/common/extensions/api/file_browser_private.h"
21 #include "ui/shell_dialogs/selected_file_info.h"
22 #include "webkit/browser/fileapi/file_system_context.h"
23 #include "webkit/browser/fileapi/file_system_url.h"
24
25 namespace file_browser_private = extensions::api::file_browser_private;
26
27 namespace file_manager {
28 namespace util {
29 namespace {
30
31 // The struct is used for GetSelectedFileInfo().
32 struct GetSelectedFileInfoParams {
33   GetSelectedFileInfoLocalPathOption local_path_option;
34   GetSelectedFileInfoCallback callback;
35   std::vector<base::FilePath> file_paths;
36   std::vector<ui::SelectedFileInfo> selected_files;
37 };
38
39 // Forward declarations of helper functions for GetSelectedFileInfo().
40 void ContinueGetSelectedFileInfo(Profile* profile,
41                                  scoped_ptr<GetSelectedFileInfoParams> params,
42                                  drive::FileError error,
43                                  const base::FilePath& local_file_path,
44                                  scoped_ptr<drive::ResourceEntry> entry);
45
46 // Part of GetSelectedFileInfo().
47 void GetSelectedFileInfoInternal(Profile* profile,
48                                  scoped_ptr<GetSelectedFileInfoParams> params) {
49   DCHECK(profile);
50   drive::FileSystemInterface* file_system =
51       drive::util::GetFileSystemByProfile(profile);
52
53   for (size_t i = params->selected_files.size();
54        i < params->file_paths.size(); ++i) {
55     const base::FilePath& file_path = params->file_paths[i];
56
57     if (!drive::util::IsUnderDriveMountPoint(file_path)) {
58       params->selected_files.push_back(
59           ui::SelectedFileInfo(file_path, base::FilePath()));
60     } else {
61       // |file_system| is NULL if Drive is disabled.
62       if (!file_system) {
63         ContinueGetSelectedFileInfo(profile,
64                                     params.Pass(),
65                                     drive::FILE_ERROR_FAILED,
66                                     base::FilePath(),
67                                     scoped_ptr<drive::ResourceEntry>());
68         return;
69       }
70       // When the caller of the select file dialog wants local file paths,
71       // we should retrieve Drive files onto the local cache.
72       switch (params->local_path_option) {
73         case NO_LOCAL_PATH_RESOLUTION:
74           params->selected_files.push_back(
75               ui::SelectedFileInfo(file_path, base::FilePath()));
76           break;
77         case NEED_LOCAL_PATH_FOR_OPENING:
78           file_system->GetFile(
79               drive::util::ExtractDrivePath(file_path),
80               base::Bind(&ContinueGetSelectedFileInfo,
81                          profile,
82                          base::Passed(&params)));
83           return;  // Remaining work is done in ContinueGetSelectedFileInfo.
84         case NEED_LOCAL_PATH_FOR_SAVING:
85           file_system->GetFileForSaving(
86               drive::util::ExtractDrivePath(file_path),
87               base::Bind(&ContinueGetSelectedFileInfo,
88                          profile,
89                          base::Passed(&params)));
90           return;  // Remaining work is done in ContinueGetSelectedFileInfo.
91       }
92     }
93   }
94   params->callback.Run(params->selected_files);
95 }
96
97 // Part of GetSelectedFileInfo().
98 void ContinueGetSelectedFileInfo(Profile* profile,
99                                  scoped_ptr<GetSelectedFileInfoParams> params,
100                                  drive::FileError error,
101                                  const base::FilePath& local_file_path,
102                                  scoped_ptr<drive::ResourceEntry> entry) {
103   DCHECK(profile);
104
105   const int index = params->selected_files.size();
106   const base::FilePath& file_path = params->file_paths[index];
107   base::FilePath local_path;
108   if (error == drive::FILE_ERROR_OK) {
109     local_path = local_file_path;
110   } else {
111     DLOG(ERROR) << "Failed to get " << file_path.value()
112                 << " with error code: " << error;
113   }
114   params->selected_files.push_back(ui::SelectedFileInfo(file_path, local_path));
115   GetSelectedFileInfoInternal(profile, params.Pass());
116 }
117
118 }  // namespace
119
120 void VolumeInfoToVolumeMetadata(
121     Profile* profile,
122     const VolumeInfo& volume_info,
123     file_browser_private::VolumeMetadata* volume_metadata) {
124   DCHECK(volume_metadata);
125   DCHECK(!volume_info.mount_path.empty());
126
127   // Convert mount point path to relative path with the external file system
128   // exposed within File API.
129   base::FilePath relative_mount_path;
130   if (ConvertAbsoluteFilePathToRelativeFileSystemPath(
131           profile, kFileManagerAppId, base::FilePath(volume_info.mount_path),
132           &relative_mount_path)) {
133     volume_metadata->mount_path = "/" + relative_mount_path.AsUTF8Unsafe();
134   }
135
136   volume_metadata->volume_id = volume_info.volume_id;
137
138   // TODO(kinaba): fill appropriate information once multi-profile support is
139   // implemented.
140   volume_metadata->profile.display_name = profile->GetProfileName();
141   volume_metadata->profile.is_current_profile = true;
142
143   if (!volume_info.source_path.empty()) {
144     volume_metadata->source_path.reset(
145         new std::string(volume_info.source_path.AsUTF8Unsafe()));
146   }
147
148   switch (volume_info.type) {
149     case VOLUME_TYPE_GOOGLE_DRIVE:
150       volume_metadata->volume_type =
151           file_browser_private::VOLUME_TYPE_DRIVE;
152       break;
153     case VOLUME_TYPE_DOWNLOADS_DIRECTORY:
154       volume_metadata->volume_type =
155           file_browser_private::VOLUME_TYPE_DOWNLOADS;
156       break;
157     case VOLUME_TYPE_REMOVABLE_DISK_PARTITION:
158       volume_metadata->volume_type =
159           file_browser_private::VOLUME_TYPE_REMOVABLE;
160       break;
161     case VOLUME_TYPE_MOUNTED_ARCHIVE_FILE:
162       volume_metadata->volume_type = file_browser_private::VOLUME_TYPE_ARCHIVE;
163       break;
164     case VOLUME_TYPE_CLOUD_DEVICE:
165       volume_metadata->volume_type =
166           file_browser_private::VOLUME_TYPE_CLOUD_DEVICE;
167       break;
168   }
169
170   // Fill device_type iff the volume is removable partition.
171   if (volume_info.type == VOLUME_TYPE_REMOVABLE_DISK_PARTITION) {
172     switch (volume_info.device_type) {
173       case chromeos::DEVICE_TYPE_UNKNOWN:
174         volume_metadata->device_type =
175             file_browser_private::DEVICE_TYPE_UNKNOWN;
176         break;
177       case chromeos::DEVICE_TYPE_USB:
178         volume_metadata->device_type = file_browser_private::DEVICE_TYPE_USB;
179         break;
180       case chromeos::DEVICE_TYPE_SD:
181         volume_metadata->device_type = file_browser_private::DEVICE_TYPE_SD;
182         break;
183       case chromeos::DEVICE_TYPE_OPTICAL_DISC:
184       case chromeos::DEVICE_TYPE_DVD:
185         volume_metadata->device_type =
186             file_browser_private::DEVICE_TYPE_OPTICAL;
187         break;
188       case chromeos::DEVICE_TYPE_MOBILE:
189         volume_metadata->device_type = file_browser_private::DEVICE_TYPE_MOBILE;
190         break;
191     }
192     volume_metadata->device_path.reset(
193         new std::string(volume_info.system_path_prefix.AsUTF8Unsafe()));
194     volume_metadata->device_label.reset(
195         new std::string(volume_info.drive_label));
196     volume_metadata->is_parent_device.reset(
197         new bool(volume_info.is_parent));
198   } else {
199     volume_metadata->device_type =
200         file_browser_private::DEVICE_TYPE_NONE;
201   }
202
203   volume_metadata->is_read_only = volume_info.is_read_only;
204
205   switch (volume_info.mount_condition) {
206     case chromeos::disks::MOUNT_CONDITION_NONE:
207       volume_metadata->mount_condition =
208           file_browser_private::MOUNT_CONDITION_NONE;
209       break;
210     case chromeos::disks::MOUNT_CONDITION_UNKNOWN_FILESYSTEM:
211       volume_metadata->mount_condition =
212           file_browser_private::MOUNT_CONDITION_UNKNOWN;
213       break;
214     case chromeos::disks::MOUNT_CONDITION_UNSUPPORTED_FILESYSTEM:
215       volume_metadata->mount_condition =
216           file_browser_private::MOUNT_CONDITION_UNSUPPORTED;
217       break;
218   }
219 }
220
221 base::FilePath GetLocalPathFromURL(content::RenderViewHost* render_view_host,
222                                    Profile* profile,
223                                    const GURL& url) {
224   DCHECK(render_view_host);
225   DCHECK(profile);
226
227   scoped_refptr<fileapi::FileSystemContext> file_system_context =
228       util::GetFileSystemContextForRenderViewHost(profile, render_view_host);
229
230   const fileapi::FileSystemURL filesystem_url(
231       file_system_context->CrackURL(url));
232   base::FilePath path;
233   if (!chromeos::FileSystemBackend::CanHandleURL(filesystem_url))
234     return base::FilePath();
235   return filesystem_url.path();
236 }
237
238 void GetSelectedFileInfo(content::RenderViewHost* render_view_host,
239                          Profile* profile,
240                          const std::vector<GURL>& file_urls,
241                          GetSelectedFileInfoLocalPathOption local_path_option,
242                          GetSelectedFileInfoCallback callback) {
243   DCHECK(render_view_host);
244   DCHECK(profile);
245
246   scoped_ptr<GetSelectedFileInfoParams> params(new GetSelectedFileInfoParams);
247   params->local_path_option = local_path_option;
248   params->callback = callback;
249
250   for (size_t i = 0; i < file_urls.size(); ++i) {
251     const GURL& file_url = file_urls[i];
252     const base::FilePath path = GetLocalPathFromURL(
253         render_view_host, profile, file_url);
254     if (!path.empty()) {
255       DVLOG(1) << "Selected: file path: " << path.value();
256       params->file_paths.push_back(path);
257     }
258   }
259
260   base::MessageLoop::current()->PostTask(
261       FROM_HERE,
262       base::Bind(&GetSelectedFileInfoInternal, profile, base::Passed(&params)));
263 }
264
265 }  // namespace util
266 }  // namespace file_manager