Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/drive/download_handler.h" | 5 #include "chrome/browser/chromeos/drive/download_handler.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/files/file_util.h" | 8 #include "base/files/file_util.h" |
| 9 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
| 10 #include "base/supports_user_data.h" | 10 #include "base/supports_user_data.h" |
| 11 #include "base/thread_task_runner_handle.h" | |
| 11 #include "base/threading/sequenced_worker_pool.h" | 12 #include "base/threading/sequenced_worker_pool.h" |
| 12 #include "chrome/browser/chromeos/drive/drive_integration_service.h" | 13 #include "chrome/browser/chromeos/drive/drive_integration_service.h" |
| 13 #include "chrome/browser/chromeos/drive/file_system_util.h" | 14 #include "chrome/browser/chromeos/drive/file_system_util.h" |
| 14 #include "chrome/browser/chromeos/drive/write_on_cache_file.h" | 15 #include "chrome/browser/chromeos/drive/write_on_cache_file.h" |
| 15 #include "chrome/browser/download/download_history.h" | 16 #include "chrome/browser/download/download_history.h" |
| 16 #include "chrome/browser/download/download_service.h" | 17 #include "chrome/browser/download/download_service.h" |
| 17 #include "chrome/browser/download/download_service_factory.h" | 18 #include "chrome/browser/download/download_service_factory.h" |
| 18 #include "components/drive/drive.pb.h" | 19 #include "components/drive/drive.pb.h" |
| 19 #include "components/drive/file_system_interface.h" | 20 #include "components/drive/file_system_interface.h" |
| 20 #include "content/public/browser/browser_thread.h" | 21 #include "content/public/browser/browser_thread.h" |
| 21 | 22 |
| 22 using content::BrowserThread; | 23 using content::BrowserThread; |
| 23 using content::DownloadManager; | 24 using content::DownloadManager; |
| 24 using content::DownloadItem; | 25 using content::DownloadItem; |
| 25 | 26 |
| 26 namespace drive { | 27 namespace drive { |
| 27 namespace { | 28 namespace { |
| 28 | 29 |
| 29 // Key for base::SupportsUserData::Data. | 30 // Key for base::SupportsUserData::Data. |
| 30 const char kDrivePathKey[] = "DrivePath"; | 31 const char kDrivePathKey[] = "DrivePath"; |
| 31 | 32 |
| 32 // Mime types that we better not trust. If the file was downloade with these | 33 // Mime types that we better not trust. If the file was downloade with these |
| 33 // mime types, while uploading to Drive we ignore it at guess by our own logic. | 34 // mime types, while uploading to Drive we ignore it at guess by our own logic. |
| 34 const char* kGenericMimeTypes[] = {"text/html", "text/plain", | 35 const char* kGenericMimeTypes[] = {"text/html", "text/plain", |
| 35 "application/octet-stream"}; | 36 "application/octet-stream"}; |
| 36 | 37 |
| 38 const int64 kDefaultRequestSpace = 512 * (1 << 20); // 512MB | |
|
hashimoto
2015/10/28 09:06:15
How was this value chosen? (based on some statisti
yawano
2015/10/28 09:29:44
No, this is not based on some statistics.
This va
| |
| 39 | |
| 40 const base::TimeDelta kFreeDiskSpaceDelay = base::TimeDelta::FromSeconds(5); | |
| 41 | |
| 37 // User Data stored in DownloadItem for drive path. | 42 // User Data stored in DownloadItem for drive path. |
| 38 class DriveUserData : public base::SupportsUserData::Data { | 43 class DriveUserData : public base::SupportsUserData::Data { |
| 39 public: | 44 public: |
| 40 explicit DriveUserData(const base::FilePath& path) : file_path_(path), | 45 explicit DriveUserData(const base::FilePath& path) : file_path_(path), |
| 41 is_complete_(false) {} | 46 is_complete_(false) {} |
| 42 ~DriveUserData() override {} | 47 ~DriveUserData() override {} |
| 43 | 48 |
| 44 const base::FilePath& file_path() const { return file_path_; } | 49 const base::FilePath& file_path() const { return file_path_; } |
| 45 const base::FilePath& cache_file_path() const { return cache_file_path_; } | 50 const base::FilePath& cache_file_path() const { return cache_file_path_; } |
| 46 void set_cache_file_path(const base::FilePath& path) { | 51 void set_cache_file_path(const base::FilePath& path) { |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 118 // 'default' fallback choice on the HTTP server. In such a case, we ignore the | 123 // 'default' fallback choice on the HTTP server. In such a case, we ignore the |
| 119 // type so that our logic can guess by its own while uploading to Drive. | 124 // type so that our logic can guess by its own while uploading to Drive. |
| 120 std::string FilterOutGenericMimeType(const std::string& mime_type) { | 125 std::string FilterOutGenericMimeType(const std::string& mime_type) { |
| 121 for (size_t i = 0; i < arraysize(kGenericMimeTypes); ++i) { | 126 for (size_t i = 0; i < arraysize(kGenericMimeTypes); ++i) { |
| 122 if (base::LowerCaseEqualsASCII(mime_type, kGenericMimeTypes[i])) | 127 if (base::LowerCaseEqualsASCII(mime_type, kGenericMimeTypes[i])) |
| 123 return std::string(); | 128 return std::string(); |
| 124 } | 129 } |
| 125 return mime_type; | 130 return mime_type; |
| 126 } | 131 } |
| 127 | 132 |
| 133 void IgnoreFreeDiskSpaceIfNeededForCallback(bool /*result*/) {} | |
| 134 | |
| 128 } // namespace | 135 } // namespace |
| 129 | 136 |
| 130 DownloadHandler::DownloadHandler(FileSystemInterface* file_system) | 137 DownloadHandler::DownloadHandler(FileSystemInterface* file_system) |
| 131 : file_system_(file_system), | 138 : file_system_(file_system), |
| 132 weak_ptr_factory_(this) { | 139 pending_request_space_(0), |
| 133 } | 140 free_disk_space_delay_(kFreeDiskSpaceDelay), |
| 141 weak_ptr_factory_(this) {} | |
| 134 | 142 |
| 135 DownloadHandler::~DownloadHandler() { | 143 DownloadHandler::~DownloadHandler() { |
| 136 } | 144 } |
| 137 | 145 |
| 138 // static | 146 // static |
| 139 DownloadHandler* DownloadHandler::GetForProfile(Profile* profile) { | 147 DownloadHandler* DownloadHandler::GetForProfile(Profile* profile) { |
| 140 DriveIntegrationService* service = | 148 DriveIntegrationService* service = |
| 141 DriveIntegrationServiceFactory::FindForProfile(profile); | 149 DriveIntegrationServiceFactory::FindForProfile(profile); |
| 142 if (!service || !service->IsMounted()) | 150 if (!service || !service->IsMounted()) |
| 143 return NULL; | 151 return NULL; |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 230 | 238 |
| 231 void DownloadHandler::CheckForFileExistence( | 239 void DownloadHandler::CheckForFileExistence( |
| 232 const DownloadItem* download, | 240 const DownloadItem* download, |
| 233 const content::CheckForFileExistenceCallback& callback) { | 241 const content::CheckForFileExistenceCallback& callback) { |
| 234 file_system_->GetResourceEntry( | 242 file_system_->GetResourceEntry( |
| 235 util::ExtractDrivePath(GetTargetPath(download)), | 243 util::ExtractDrivePath(GetTargetPath(download)), |
| 236 base::Bind(&ContinueCheckingForFileExistence, | 244 base::Bind(&ContinueCheckingForFileExistence, |
| 237 callback)); | 245 callback)); |
| 238 } | 246 } |
| 239 | 247 |
| 248 void DownloadHandler::SetFreeDiskSpaceDelayForTesting( | |
| 249 const base::TimeDelta& delay) { | |
| 250 free_disk_space_delay_ = delay; | |
| 251 } | |
| 252 | |
| 253 // TODO(yawano): support multiple in-progress downloads. | |
|
hashimoto
2015/10/28 09:06:15
Why don't you support multiple downloads now?
yawano
2015/10/28 09:29:44
I thought it will make this CL larger. But I think
| |
| 254 void DownloadHandler::FreeDiskSpaceIfNeeded(const DownloadItem* download, | |
| 255 bool immediate) { | |
| 256 if (download->IsDone()) | |
| 257 return; | |
| 258 | |
| 259 const int64 total_bytes = download->GetTotalBytes(); | |
| 260 const int64 request_space = total_bytes == 0 | |
|
hashimoto
2015/10/28 09:06:15
Please add a comment why we need to handle total_b
yawano
2015/10/29 02:52:43
Done.
| |
| 261 ? kDefaultRequestSpace | |
|
hashimoto
2015/10/28 09:06:15
IIUC, when the download is 99% complete, this can
yawano
2015/10/28 09:29:44
This value is used when we don't know total bytes
| |
| 262 : total_bytes - download->GetReceivedBytes(); | |
| 263 | |
| 264 if (immediate) { | |
| 265 file_system_->FreeDiskSpaceIfNeededFor( | |
| 266 request_space, base::Bind(&IgnoreFreeDiskSpaceIfNeededForCallback)); | |
| 267 | |
| 268 return; | |
| 269 } | |
| 270 | |
| 271 const bool post_task = pending_request_space_ == 0; | |
| 272 pending_request_space_ = request_space; | |
| 273 | |
| 274 if (post_task) { | |
| 275 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | |
| 276 FROM_HERE, base::Bind(&DownloadHandler::ExecuteFreeDiskSpaceIfNeededFor, | |
| 277 weak_ptr_factory_.GetWeakPtr()), | |
| 278 free_disk_space_delay_); | |
| 279 } | |
| 280 } | |
| 281 | |
| 240 void DownloadHandler::OnDownloadCreated(DownloadManager* manager, | 282 void DownloadHandler::OnDownloadCreated(DownloadManager* manager, |
| 241 DownloadItem* download) { | 283 DownloadItem* download) { |
| 284 FreeDiskSpaceIfNeeded(download, true /* immediate */); | |
| 285 | |
| 242 // Remove any persisted Drive DownloadItem. crbug.com/171384 | 286 // Remove any persisted Drive DownloadItem. crbug.com/171384 |
| 243 if (IsPersistedDriveDownload(drive_tmp_download_path_, download)) { | 287 if (IsPersistedDriveDownload(drive_tmp_download_path_, download)) { |
| 244 // Remove download later, since doing it here results in a crash. | 288 // Remove download later, since doing it here results in a crash. |
| 245 BrowserThread::PostTask(BrowserThread::UI, | 289 BrowserThread::PostTask(BrowserThread::UI, |
| 246 FROM_HERE, | 290 FROM_HERE, |
| 247 base::Bind(&DownloadHandler::RemoveDownload, | 291 base::Bind(&DownloadHandler::RemoveDownload, |
| 248 weak_ptr_factory_.GetWeakPtr(), | 292 weak_ptr_factory_.GetWeakPtr(), |
| 249 static_cast<void*>(manager), | 293 static_cast<void*>(manager), |
| 250 download->GetId())); | 294 download->GetId())); |
| 251 } | 295 } |
| 252 } | 296 } |
| 253 | 297 |
| 254 void DownloadHandler::RemoveDownload(void* manager_id, int id) { | 298 void DownloadHandler::RemoveDownload(void* manager_id, int id) { |
| 255 DownloadManager* manager = GetDownloadManager(manager_id); | 299 DownloadManager* manager = GetDownloadManager(manager_id); |
| 256 if (!manager) | 300 if (!manager) |
| 257 return; | 301 return; |
| 258 DownloadItem* download = manager->GetDownload(id); | 302 DownloadItem* download = manager->GetDownload(id); |
| 259 if (!download) | 303 if (!download) |
| 260 return; | 304 return; |
| 261 download->Remove(); | 305 download->Remove(); |
| 262 } | 306 } |
| 263 | 307 |
| 264 void DownloadHandler::OnDownloadUpdated( | 308 void DownloadHandler::OnDownloadUpdated( |
| 265 DownloadManager* manager, DownloadItem* download) { | 309 DownloadManager* manager, DownloadItem* download) { |
| 266 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 310 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 267 | 311 |
| 312 FreeDiskSpaceIfNeeded(download, false /* not immediate */); | |
| 313 | |
| 268 // Only accept downloads that have the Drive meta data associated with them. | 314 // Only accept downloads that have the Drive meta data associated with them. |
| 269 DriveUserData* data = GetDriveUserData(download); | 315 DriveUserData* data = GetDriveUserData(download); |
| 270 if (!drive_tmp_download_path_.IsParent(download->GetTargetFilePath()) || | 316 if (!drive_tmp_download_path_.IsParent(download->GetTargetFilePath()) || |
| 271 !data || | 317 !data || |
| 272 data->is_complete()) | 318 data->is_complete()) |
| 273 return; | 319 return; |
| 274 | 320 |
| 275 switch (download->GetState()) { | 321 switch (download->GetState()) { |
| 276 case DownloadItem::IN_PROGRESS: | 322 case DownloadItem::IN_PROGRESS: |
| 277 break; | 323 break; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 338 return; | 384 return; |
| 339 DownloadItem* download = manager->GetDownload(id); | 385 DownloadItem* download = manager->GetDownload(id); |
| 340 if (!download) | 386 if (!download) |
| 341 return; | 387 return; |
| 342 DriveUserData* data = GetDriveUserData(download); | 388 DriveUserData* data = GetDriveUserData(download); |
| 343 if (!data) | 389 if (!data) |
| 344 return; | 390 return; |
| 345 data->set_cache_file_path(*cache_file_path); | 391 data->set_cache_file_path(*cache_file_path); |
| 346 } | 392 } |
| 347 | 393 |
| 394 void DownloadHandler::ExecuteFreeDiskSpaceIfNeededFor() { | |
| 395 file_system_->FreeDiskSpaceIfNeededFor( | |
| 396 pending_request_space_, | |
| 397 base::Bind(&IgnoreFreeDiskSpaceIfNeededForCallback)); | |
| 398 | |
| 399 pending_request_space_ = 0; | |
| 400 } | |
| 401 | |
| 348 DownloadManager* DownloadHandler::GetDownloadManager(void* manager_id) { | 402 DownloadManager* DownloadHandler::GetDownloadManager(void* manager_id) { |
| 349 if (manager_id == notifier_->GetManager()) | 403 if (manager_id == notifier_->GetManager()) |
| 350 return notifier_->GetManager(); | 404 return notifier_->GetManager(); |
| 351 if (notifier_incognito_ && manager_id == notifier_incognito_->GetManager()) | 405 if (notifier_incognito_ && manager_id == notifier_incognito_->GetManager()) |
| 352 return notifier_incognito_->GetManager(); | 406 return notifier_incognito_->GetManager(); |
| 353 return NULL; | 407 return NULL; |
| 354 } | 408 } |
| 355 | 409 |
| 356 } // namespace drive | 410 } // namespace drive |
| OLD | NEW |