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