Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / chromeos / extensions / file_manager / private_api_util.cc
bloba220fe889ae00c1891a445372bb38789936b9d10
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_manager/private_api_util.h"
7 #include <string>
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/drive_integration_service.h"
13 #include "chrome/browser/chromeos/drive/file_errors.h"
14 #include "chrome/browser/chromeos/drive/file_system_interface.h"
15 #include "chrome/browser/chromeos/drive/file_system_util.h"
16 #include "chrome/browser/chromeos/file_manager/app_id.h"
17 #include "chrome/browser/chromeos/file_manager/fileapi_util.h"
18 #include "chrome/browser/chromeos/file_manager/filesystem_api_util.h"
19 #include "chrome/browser/chromeos/file_manager/path_util.h"
20 #include "chrome/browser/chromeos/file_manager/snapshot_manager.h"
21 #include "chrome/browser/chromeos/file_manager/volume_manager.h"
22 #include "chrome/browser/chromeos/fileapi/file_system_backend.h"
23 #include "chrome/browser/profiles/profile.h"
24 #include "chrome/common/extensions/api/file_manager_private.h"
25 #include "content/public/browser/child_process_security_policy.h"
26 #include "storage/browser/fileapi/file_system_context.h"
27 #include "storage/browser/fileapi/file_system_url.h"
28 #include "ui/shell_dialogs/selected_file_info.h"
30 namespace file_manager_private = extensions::api::file_manager_private;
32 namespace file_manager {
33 namespace util {
34 namespace {
36 // The struct is used for GetSelectedFileInfo().
37 struct GetSelectedFileInfoParams {
38 GetSelectedFileInfoLocalPathOption local_path_option;
39 GetSelectedFileInfoCallback callback;
40 std::vector<base::FilePath> file_paths;
41 std::vector<ui::SelectedFileInfo> selected_files;
44 // The callback type for GetFileNativeLocalPathFor{Opening,Saving}. It receives
45 // the resolved local path when successful, and receives empty path for failure.
46 typedef base::Callback<void(const base::FilePath&)> LocalPathCallback;
48 // Converts a callback from Drive file system to LocalPathCallback.
49 void OnDriveGetFile(const base::FilePath& path,
50 const LocalPathCallback& callback,
51 drive::FileError error,
52 const base::FilePath& local_file_path,
53 scoped_ptr<drive::ResourceEntry> entry) {
54 if (error != drive::FILE_ERROR_OK)
55 DLOG(ERROR) << "Failed to get " << path.value() << " with: " << error;
56 callback.Run(local_file_path);
59 // Gets a resolved local file path of a non native |path| for file opening.
60 void GetFileNativeLocalPathForOpening(Profile* profile,
61 const base::FilePath& path,
62 const LocalPathCallback& callback) {
63 if (drive::util::IsUnderDriveMountPoint(path)) {
64 drive::FileSystemInterface* file_system =
65 drive::util::GetFileSystemByProfile(profile);
66 if (!file_system) {
67 DLOG(ERROR) << "Drive file selected while disabled: " << path.value();
68 callback.Run(base::FilePath());
69 return;
71 file_system->GetFile(drive::util::ExtractDrivePath(path),
72 base::Bind(&OnDriveGetFile, path, callback));
73 return;
76 VolumeManager::Get(profile)->snapshot_manager()->CreateManagedSnapshot(
77 path, callback);
80 // Gets a resolved local file path of a non native |path| for file saving.
81 void GetFileNativeLocalPathForSaving(Profile* profile,
82 const base::FilePath& path,
83 const LocalPathCallback& callback) {
84 if (drive::util::IsUnderDriveMountPoint(path)) {
85 drive::FileSystemInterface* file_system =
86 drive::util::GetFileSystemByProfile(profile);
87 if (!file_system) {
88 DLOG(ERROR) << "Drive file selected while disabled: " << path.value();
89 callback.Run(base::FilePath());
90 return;
92 file_system->GetFileForSaving(drive::util::ExtractDrivePath(path),
93 base::Bind(&OnDriveGetFile, path, callback));
94 return;
97 // TODO(kinaba): For now, the only writable non-local volume is Drive.
98 NOTREACHED();
99 callback.Run(base::FilePath());
102 // Forward declarations of helper functions for GetSelectedFileInfo().
103 void ContinueGetSelectedFileInfo(Profile* profile,
104 scoped_ptr<GetSelectedFileInfoParams> params,
105 const base::FilePath& local_file_path);
107 // Part of GetSelectedFileInfo().
108 void GetSelectedFileInfoInternal(Profile* profile,
109 scoped_ptr<GetSelectedFileInfoParams> params) {
110 DCHECK(profile);
112 for (size_t i = params->selected_files.size();
113 i < params->file_paths.size(); ++i) {
114 const base::FilePath& file_path = params->file_paths[i];
116 if (file_manager::util::IsUnderNonNativeLocalPath(profile, file_path)) {
117 // When the caller of the select file dialog wants local file paths, and
118 // the selected path does not point to a native local path (e.g., Drive,
119 // MTP, or provided file system), we should resolve the path.
120 switch (params->local_path_option) {
121 case NO_LOCAL_PATH_RESOLUTION:
122 // Pass empty local path.
123 params->selected_files.push_back(
124 ui::SelectedFileInfo(file_path, base::FilePath()));
125 break;
126 case NEED_LOCAL_PATH_FOR_OPENING:
127 GetFileNativeLocalPathForOpening(
128 profile,
129 file_path,
130 base::Bind(&ContinueGetSelectedFileInfo,
131 profile,
132 base::Passed(&params)));
133 return; // Remaining work is done in ContinueGetSelectedFileInfo.
134 case NEED_LOCAL_PATH_FOR_SAVING:
135 GetFileNativeLocalPathForSaving(
136 profile,
137 file_path,
138 base::Bind(&ContinueGetSelectedFileInfo,
139 profile,
140 base::Passed(&params)));
141 return; // Remaining work is done in ContinueGetSelectedFileInfo.
143 } else {
144 params->selected_files.push_back(
145 ui::SelectedFileInfo(file_path, file_path));
148 params->callback.Run(params->selected_files);
151 // Part of GetSelectedFileInfo().
152 void ContinueGetSelectedFileInfo(Profile* profile,
153 scoped_ptr<GetSelectedFileInfoParams> params,
154 const base::FilePath& local_path) {
155 if (local_path.empty()) {
156 params->callback.Run(std::vector<ui::SelectedFileInfo>());
157 return;
159 const int index = params->selected_files.size();
160 const base::FilePath& file_path = params->file_paths[index];
161 params->selected_files.push_back(ui::SelectedFileInfo(file_path, local_path));
162 GetSelectedFileInfoInternal(profile, params.Pass());
165 } // namespace
167 void VolumeToVolumeMetadata(
168 Profile* profile,
169 const Volume& volume,
170 file_manager_private::VolumeMetadata* volume_metadata) {
171 DCHECK(volume_metadata);
173 volume_metadata->volume_id = volume.volume_id();
175 // TODO(kinaba): fill appropriate information once multi-profile support is
176 // implemented.
177 volume_metadata->profile.display_name = profile->GetProfileUserName();
178 volume_metadata->profile.is_current_profile = true;
180 if (!volume.source_path().empty()) {
181 volume_metadata->source_path.reset(
182 new std::string(volume.source_path().AsUTF8Unsafe()));
185 if (volume.type() == VOLUME_TYPE_PROVIDED) {
186 volume_metadata->extension_id.reset(new std::string(volume.extension_id()));
188 volume_metadata->file_system_id.reset(
189 new std::string(volume.file_system_id()));
192 volume_metadata->volume_label.reset(new std::string(volume.volume_label()));
194 switch (volume.type()) {
195 case VOLUME_TYPE_GOOGLE_DRIVE:
196 volume_metadata->volume_type =
197 file_manager_private::VOLUME_TYPE_DRIVE;
198 break;
199 case VOLUME_TYPE_DOWNLOADS_DIRECTORY:
200 volume_metadata->volume_type =
201 file_manager_private::VOLUME_TYPE_DOWNLOADS;
202 break;
203 case VOLUME_TYPE_REMOVABLE_DISK_PARTITION:
204 volume_metadata->volume_type =
205 file_manager_private::VOLUME_TYPE_REMOVABLE;
206 break;
207 case VOLUME_TYPE_MOUNTED_ARCHIVE_FILE:
208 volume_metadata->volume_type = file_manager_private::VOLUME_TYPE_ARCHIVE;
209 break;
210 case VOLUME_TYPE_CLOUD_DEVICE:
211 volume_metadata->volume_type =
212 file_manager_private::VOLUME_TYPE_CLOUD_DEVICE;
213 break;
214 case VOLUME_TYPE_PROVIDED:
215 volume_metadata->volume_type = file_manager_private::VOLUME_TYPE_PROVIDED;
216 break;
217 case VOLUME_TYPE_MTP:
218 volume_metadata->volume_type = file_manager_private::VOLUME_TYPE_MTP;
219 break;
220 case VOLUME_TYPE_TESTING:
221 volume_metadata->volume_type =
222 file_manager_private::VOLUME_TYPE_TESTING;
223 break;
224 case NUM_VOLUME_TYPE:
225 NOTREACHED();
226 break;
229 // Fill device_type iff the volume is removable partition.
230 if (volume.type() == VOLUME_TYPE_REMOVABLE_DISK_PARTITION) {
231 switch (volume.device_type()) {
232 case chromeos::DEVICE_TYPE_UNKNOWN:
233 volume_metadata->device_type =
234 file_manager_private::DEVICE_TYPE_UNKNOWN;
235 break;
236 case chromeos::DEVICE_TYPE_USB:
237 volume_metadata->device_type = file_manager_private::DEVICE_TYPE_USB;
238 break;
239 case chromeos::DEVICE_TYPE_SD:
240 volume_metadata->device_type = file_manager_private::DEVICE_TYPE_SD;
241 break;
242 case chromeos::DEVICE_TYPE_OPTICAL_DISC:
243 case chromeos::DEVICE_TYPE_DVD:
244 volume_metadata->device_type =
245 file_manager_private::DEVICE_TYPE_OPTICAL;
246 break;
247 case chromeos::DEVICE_TYPE_MOBILE:
248 volume_metadata->device_type = file_manager_private::DEVICE_TYPE_MOBILE;
249 break;
251 volume_metadata->device_path.reset(
252 new std::string(volume.system_path_prefix().AsUTF8Unsafe()));
253 volume_metadata->is_parent_device.reset(new bool(volume.is_parent()));
254 } else {
255 volume_metadata->device_type =
256 file_manager_private::DEVICE_TYPE_NONE;
259 volume_metadata->is_read_only = volume.is_read_only();
260 volume_metadata->has_media = volume.has_media();
262 switch (volume.mount_condition()) {
263 case chromeos::disks::MOUNT_CONDITION_NONE:
264 volume_metadata->mount_condition =
265 file_manager_private::MOUNT_CONDITION_NONE;
266 break;
267 case chromeos::disks::MOUNT_CONDITION_UNKNOWN_FILESYSTEM:
268 volume_metadata->mount_condition =
269 file_manager_private::MOUNT_CONDITION_UNKNOWN;
270 break;
271 case chromeos::disks::MOUNT_CONDITION_UNSUPPORTED_FILESYSTEM:
272 volume_metadata->mount_condition =
273 file_manager_private::MOUNT_CONDITION_UNSUPPORTED;
274 break;
277 // If the context is known, then pass it.
278 switch (volume.mount_context()) {
279 case MOUNT_CONTEXT_USER:
280 volume_metadata->mount_context = file_manager_private::MOUNT_CONTEXT_USER;
281 break;
282 case MOUNT_CONTEXT_AUTO:
283 volume_metadata->mount_context = file_manager_private::MOUNT_CONTEXT_AUTO;
284 break;
285 case MOUNT_CONTEXT_UNKNOWN:
286 break;
290 base::FilePath GetLocalPathFromURL(content::RenderViewHost* render_view_host,
291 Profile* profile,
292 const GURL& url) {
293 DCHECK(render_view_host);
294 DCHECK(profile);
296 scoped_refptr<storage::FileSystemContext> file_system_context =
297 util::GetFileSystemContextForRenderViewHost(profile, render_view_host);
299 const storage::FileSystemURL filesystem_url(
300 file_system_context->CrackURL(url));
301 base::FilePath path;
302 if (!chromeos::FileSystemBackend::CanHandleURL(filesystem_url))
303 return base::FilePath();
304 return filesystem_url.path();
307 void GetSelectedFileInfo(content::RenderViewHost* render_view_host,
308 Profile* profile,
309 const std::vector<GURL>& file_urls,
310 GetSelectedFileInfoLocalPathOption local_path_option,
311 GetSelectedFileInfoCallback callback) {
312 DCHECK(render_view_host);
313 DCHECK(profile);
315 scoped_ptr<GetSelectedFileInfoParams> params(new GetSelectedFileInfoParams);
316 params->local_path_option = local_path_option;
317 params->callback = callback;
319 for (size_t i = 0; i < file_urls.size(); ++i) {
320 const GURL& file_url = file_urls[i];
321 const base::FilePath path = GetLocalPathFromURL(
322 render_view_host, profile, file_url);
323 if (!path.empty()) {
324 DVLOG(1) << "Selected: file path: " << path.value();
325 params->file_paths.push_back(path);
329 base::MessageLoop::current()->PostTask(
330 FROM_HERE,
331 base::Bind(&GetSelectedFileInfoInternal, profile, base::Passed(&params)));
334 void SetupProfileFileAccessPermissions(int render_view_process_id,
335 Profile* profile) {
336 const base::FilePath paths[] = {
337 drive::util::GetDriveMountPointPath(profile),
338 util::GetDownloadsFolderForProfile(profile),
340 for (size_t i = 0; i < arraysize(paths); ++i) {
341 content::ChildProcessSecurityPolicy::GetInstance(
342 )->GrantCreateReadWriteFile(render_view_process_id, paths[i]);
346 drive::EventLogger* GetLogger(Profile* profile) {
347 drive::DriveIntegrationService* service =
348 drive::DriveIntegrationServiceFactory::FindForProfile(profile);
349 return service ? service->event_logger() : NULL;
352 } // namespace util
353 } // namespace file_manager