Chromium Code Reviews| Index: chrome/browser/chromeos/drive/download_handler.cc |
| diff --git a/chrome/browser/chromeos/drive/download_handler.cc b/chrome/browser/chromeos/drive/download_handler.cc |
| index 06bc182a95e4b6ab800ca456ebabdf87543cdf75..4186b6589af4404b30229bf7deb0c6e067ee85f7 100644 |
| --- a/chrome/browser/chromeos/drive/download_handler.cc |
| +++ b/chrome/browser/chromeos/drive/download_handler.cc |
| @@ -8,6 +8,7 @@ |
| #include "base/files/file_util.h" |
| #include "base/strings/string_util.h" |
| #include "base/supports_user_data.h" |
| +#include "base/thread_task_runner_handle.h" |
| #include "base/threading/sequenced_worker_pool.h" |
| #include "chrome/browser/chromeos/drive/drive_integration_service.h" |
| #include "chrome/browser/chromeos/drive/file_system_util.h" |
| @@ -34,6 +35,11 @@ const char kDrivePathKey[] = "DrivePath"; |
| const char* kGenericMimeTypes[] = {"text/html", "text/plain", |
| "application/octet-stream"}; |
| +// Longer is better. But at the same time, this value should be short enough as |
| +// drive::internal::kMinFreeSpaceInBytes is not used up by file download in this |
| +// interval. |
| +const base::TimeDelta kFreeDiskSpaceDelay = base::TimeDelta::FromSeconds(3); |
| + |
| // User Data stored in DownloadItem for drive path. |
| class DriveUserData : public base::SupportsUserData::Data { |
| public: |
| @@ -125,12 +131,15 @@ std::string FilterOutGenericMimeType(const std::string& mime_type) { |
| return mime_type; |
| } |
| +void IgnoreFreeDiskSpaceIfNeededForCallback(bool /*result*/) {} |
| + |
| } // namespace |
| DownloadHandler::DownloadHandler(FileSystemInterface* file_system) |
| : file_system_(file_system), |
| - weak_ptr_factory_(this) { |
| -} |
| + has_pending_free_disk_space_(false), |
| + free_disk_space_delay_(kFreeDiskSpaceDelay), |
| + weak_ptr_factory_(this) {} |
| DownloadHandler::~DownloadHandler() { |
| } |
| @@ -237,8 +246,65 @@ void DownloadHandler::CheckForFileExistence( |
| callback)); |
| } |
| +void DownloadHandler::SetFreeDiskSpaceDelayForTesting( |
| + const base::TimeDelta& delay) { |
| + free_disk_space_delay_ = delay; |
| +} |
| + |
| +int64 DownloadHandler::CalculateRequestSpace( |
| + const DownloadManager::DownloadVector& downloads) { |
| + int64 request_space = 0; |
| + |
| + for (const auto* download : downloads) { |
| + if (download->IsDone()) |
| + continue; |
| + |
| + const int64 total_bytes = download->GetTotalBytes(); |
| + // Skip unknown size download. Since drive cache tries to keep |
| + // drive::internal::kMinFreeSpaceInBytes, we can continue download with |
| + // using the space temporally. |
| + if (total_bytes == 0) |
| + continue; |
| + |
| + request_space += total_bytes - download->GetReceivedBytes(); |
| + } |
| + |
| + return request_space; |
| +} |
| + |
| +void DownloadHandler::FreeDiskSpaceIfNeeded() { |
| + if (has_pending_free_disk_space_) |
| + return; |
| + |
| + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| + FROM_HERE, base::Bind(&DownloadHandler::FreeDiskSpaceIfNeededImmediately, |
| + weak_ptr_factory_.GetWeakPtr()), |
| + free_disk_space_delay_); |
| + |
| + has_pending_free_disk_space_ = true; |
| +} |
| + |
| +void DownloadHandler::FreeDiskSpaceIfNeededImmediately() { |
| + DownloadManager::DownloadVector downloads; |
| + |
| + if (notifier_ != nullptr) |
| + notifier_->GetManager()->GetAllDownloads(&downloads); |
|
hashimoto
2015/10/30 09:33:43
GetManager() can return nullptr. Don't we need to
yawano
2015/11/02 07:26:20
Yes, we should. Thank you!
|
| + if (notifier_incognito_ != nullptr) |
| + notifier_incognito_->GetManager()->GetAllDownloads(&downloads); |
|
hashimoto
2015/10/30 09:33:43
qq: IIUC this code is intended to get all download
yawano
2015/11/02 07:26:19
This gets all downloads of current profile and its
|
| + |
| + // Free disk space even if request size is 0 byte in order to make drive cache |
| + // keep drive::internal::kMinFreeSpaceInBytes. |
| + file_system_->FreeDiskSpaceIfNeededFor( |
| + CalculateRequestSpace(downloads), |
| + base::Bind(&IgnoreFreeDiskSpaceIfNeededForCallback)); |
| + |
| + has_pending_free_disk_space_ = false; |
| +} |
| + |
| void DownloadHandler::OnDownloadCreated(DownloadManager* manager, |
| DownloadItem* download) { |
| + FreeDiskSpaceIfNeededImmediately(); |
| + |
| // Remove any persisted Drive DownloadItem. crbug.com/171384 |
| if (IsPersistedDriveDownload(drive_tmp_download_path_, download)) { |
| // Remove download later, since doing it here results in a crash. |
| @@ -265,6 +331,8 @@ void DownloadHandler::OnDownloadUpdated( |
| DownloadManager* manager, DownloadItem* download) { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| + FreeDiskSpaceIfNeeded(); |
| + |
| // Only accept downloads that have the Drive meta data associated with them. |
| DriveUserData* data = GetDriveUserData(download); |
| if (!drive_tmp_download_path_.IsParent(download->GetTargetFilePath()) || |