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