ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / chrome / browser / chromeos / extensions / file_manager / private_api_mount.cc
blob877801e751af9b3411bb6ad70bd224d46fdbd5db
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_mount.h"
7 #include <string>
9 #include "base/files/file_util.h"
10 #include "base/format_macros.h"
11 #include "chrome/browser/chromeos/drive/file_system_interface.h"
12 #include "chrome/browser/chromeos/drive/file_system_util.h"
13 #include "chrome/browser/chromeos/extensions/file_manager/private_api_util.h"
14 #include "chrome/browser/chromeos/file_manager/fileapi_util.h"
15 #include "chrome/browser/chromeos/file_manager/volume_manager.h"
16 #include "chrome/browser/drive/event_logger.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/common/extensions/api/file_manager_private.h"
19 #include "chromeos/disks/disk_mount_manager.h"
20 #include "content/public/browser/browser_thread.h"
21 #include "google_apis/drive/task_util.h"
22 #include "ui/shell_dialogs/selected_file_info.h"
24 using chromeos::disks::DiskMountManager;
25 using content::BrowserThread;
26 namespace file_manager_private = extensions::api::file_manager_private;
28 namespace extensions {
30 namespace {
32 // Does chmod o+r for the given path to ensure the file is readable from avfs.
33 void EnsureReadableFilePermissionOnBlockingPool(
34 const base::FilePath& path,
35 const base::Callback<void(drive::FileError, const base::FilePath&)>&
36 callback) {
37 int mode = 0;
38 if (!base::GetPosixFilePermissions(path, &mode) ||
39 !base::SetPosixFilePermissions(path, mode | S_IROTH)) {
40 callback.Run(drive::FILE_ERROR_ACCESS_DENIED, base::FilePath());
41 return;
43 callback.Run(drive::FILE_ERROR_OK, path);
46 } // namespace
48 bool FileManagerPrivateAddMountFunction::RunAsync() {
49 using file_manager_private::AddMount::Params;
50 const scoped_ptr<Params> params(Params::Create(*args_));
51 EXTENSION_FUNCTION_VALIDATE(params);
53 drive::EventLogger* logger = file_manager::util::GetLogger(GetProfile());
54 if (logger) {
55 logger->Log(logging::LOG_INFO, "%s[%d] called. (source: '%s')", name(),
56 request_id(),
57 params->source.empty() ? "(none)" : params->source.c_str());
59 set_log_on_completion(true);
61 const base::FilePath path = file_manager::util::GetLocalPathFromURL(
62 render_view_host(), GetProfile(), GURL(params->source));
64 if (path.empty())
65 return false;
67 // Check if the source path is under Drive cache directory.
68 if (drive::util::IsUnderDriveMountPoint(path)) {
69 drive::FileSystemInterface* file_system =
70 drive::util::GetFileSystemByProfile(GetProfile());
71 if (!file_system)
72 return false;
74 // Ensure that the cache file exists.
75 const base::FilePath drive_path = drive::util::ExtractDrivePath(path);
76 file_system->GetFile(
77 drive_path,
78 base::Bind(&FileManagerPrivateAddMountFunction::RunAfterGetDriveFile,
79 this,
80 drive_path));
81 } else {
82 file_manager::VolumeManager* volume_manager =
83 file_manager::VolumeManager::Get(GetProfile());
84 DCHECK(volume_manager);
86 bool is_under_downloads = false;
87 const std::vector<file_manager::VolumeInfo> volumes =
88 volume_manager->GetVolumeInfoList();
89 for (size_t i = 0; i < volumes.size(); ++i) {
90 if (volumes[i].type == file_manager::VOLUME_TYPE_DOWNLOADS_DIRECTORY &&
91 volumes[i].mount_path.IsParent(path)) {
92 is_under_downloads = true;
93 break;
97 if (is_under_downloads) {
98 // For files under downloads, change the file permission and make it
99 // readable from avfs/fuse if needed.
100 BrowserThread::PostBlockingPoolTask(
101 FROM_HERE,
102 base::Bind(&EnsureReadableFilePermissionOnBlockingPool,
103 path,
104 google_apis::CreateRelayCallback(
105 base::Bind(&FileManagerPrivateAddMountFunction::
106 RunAfterMarkCacheFileAsMounted,
107 this,
108 path.BaseName()))));
109 } else {
110 RunAfterMarkCacheFileAsMounted(
111 path.BaseName(), drive::FILE_ERROR_OK, path);
114 return true;
117 void FileManagerPrivateAddMountFunction::RunAfterGetDriveFile(
118 const base::FilePath& drive_path,
119 drive::FileError error,
120 const base::FilePath& cache_path,
121 scoped_ptr<drive::ResourceEntry> entry) {
122 DCHECK_CURRENTLY_ON(BrowserThread::UI);
124 if (error != drive::FILE_ERROR_OK) {
125 SendResponse(false);
126 return;
129 drive::FileSystemInterface* const file_system =
130 drive::util::GetFileSystemByProfile(GetProfile());
131 if (!file_system) {
132 SendResponse(false);
133 return;
136 file_system->MarkCacheFileAsMounted(
137 drive_path,
138 base::Bind(
139 &FileManagerPrivateAddMountFunction::RunAfterMarkCacheFileAsMounted,
140 this,
141 drive_path.BaseName()));
144 void FileManagerPrivateAddMountFunction::RunAfterMarkCacheFileAsMounted(
145 const base::FilePath& display_name,
146 drive::FileError error,
147 const base::FilePath& file_path) {
148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
150 if (error != drive::FILE_ERROR_OK) {
151 SendResponse(false);
152 return;
155 // Pass back the actual source path of the mount point.
156 SetResult(new base::StringValue(file_path.AsUTF8Unsafe()));
157 SendResponse(true);
159 // MountPath() takes a std::string.
160 DiskMountManager* disk_mount_manager = DiskMountManager::GetInstance();
161 disk_mount_manager->MountPath(
162 file_path.AsUTF8Unsafe(),
163 base::FilePath(display_name.Extension()).AsUTF8Unsafe(),
164 display_name.AsUTF8Unsafe(),
165 chromeos::MOUNT_TYPE_ARCHIVE);
168 bool FileManagerPrivateRemoveMountFunction::RunAsync() {
169 using file_manager_private::RemoveMount::Params;
170 const scoped_ptr<Params> params(Params::Create(*args_));
171 EXTENSION_FUNCTION_VALIDATE(params);
173 drive::EventLogger* logger = file_manager::util::GetLogger(GetProfile());
174 if (logger) {
175 logger->Log(logging::LOG_INFO, "%s[%d] called. (volume_id: '%s')", name(),
176 request_id(), params->volume_id.c_str());
178 set_log_on_completion(true);
180 using file_manager::VolumeManager;
181 using file_manager::VolumeInfo;
182 VolumeManager* volume_manager = VolumeManager::Get(GetProfile());
183 DCHECK(volume_manager);
185 VolumeInfo volume_info;
186 if (!volume_manager->FindVolumeInfoById(params->volume_id, &volume_info))
187 return false;
189 // TODO(tbarzic): Send response when callback is received, it would make more
190 // sense than remembering issued unmount requests in file manager and showing
191 // errors for them when MountCompleted event is received.
192 switch (volume_info.type) {
193 case file_manager::VOLUME_TYPE_REMOVABLE_DISK_PARTITION:
194 case file_manager::VOLUME_TYPE_MOUNTED_ARCHIVE_FILE: {
195 DiskMountManager::GetInstance()->UnmountPath(
196 volume_info.mount_path.value(),
197 chromeos::UNMOUNT_OPTIONS_NONE,
198 DiskMountManager::UnmountPathCallback());
199 break;
201 case file_manager::VOLUME_TYPE_PROVIDED: {
202 chromeos::file_system_provider::Service* service =
203 chromeos::file_system_provider::Service::Get(GetProfile());
204 DCHECK(service);
205 // TODO(mtomasz): Pass a more detailed error than just a bool.
206 if (!service->RequestUnmount(volume_info.extension_id,
207 volume_info.file_system_id)) {
208 return false;
210 break;
212 default:
213 // Requested unmounting a device which is not unmountable.
214 return false;
217 SendResponse(true);
218 return true;
221 bool FileManagerPrivateGetVolumeMetadataListFunction::RunAsync() {
222 if (args_->GetSize())
223 return false;
225 const std::vector<file_manager::VolumeInfo>& volume_info_list =
226 file_manager::VolumeManager::Get(GetProfile())->GetVolumeInfoList();
228 std::string log_string;
229 std::vector<linked_ptr<file_manager_private::VolumeMetadata> > result;
230 for (size_t i = 0; i < volume_info_list.size(); ++i) {
231 linked_ptr<file_manager_private::VolumeMetadata> volume_metadata(
232 new file_manager_private::VolumeMetadata);
233 file_manager::util::VolumeInfoToVolumeMetadata(
234 GetProfile(), volume_info_list[i], volume_metadata.get());
235 result.push_back(volume_metadata);
236 if (!log_string.empty())
237 log_string += ", ";
238 log_string += volume_info_list[i].mount_path.AsUTF8Unsafe();
241 drive::EventLogger* logger = file_manager::util::GetLogger(GetProfile());
242 if (logger) {
243 logger->Log(logging::LOG_INFO,
244 "%s[%d] succeeded. (results: '[%s]', %" PRIuS " mount points)",
245 name(), request_id(), log_string.c_str(), result.size());
248 results_ =
249 file_manager_private::GetVolumeMetadataList::Results::Create(result);
250 SendResponse(true);
251 return true;
254 } // namespace extensions