| 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..0e6897bff890b5d791e7f89cf9758316d718ad24 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,69 @@ 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;
|
| +
|
| + // Get all downloads of current profile and its off-the-record profile.
|
| + // TODO(yawano): support multi profiles.
|
| + if (notifier_ && notifier_->GetManager()) {
|
| + notifier_->GetManager()->GetAllDownloads(&downloads);
|
| + }
|
| + if (notifier_incognito_ && notifier_incognito_->GetManager()) {
|
| + notifier_incognito_->GetManager()->GetAllDownloads(&downloads);
|
| + }
|
| +
|
| + // 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 +335,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()) ||
|
|
|