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 // Longer is better. But at the same time, this value should be short enough as |
| 39 // drive::internal::kMinFreeSpaceInBytes is not used up by file download in this |
| 40 // interval. |
| 41 const base::TimeDelta kFreeDiskSpaceDelay = base::TimeDelta::FromSeconds(3); |
| 42 |
37 // User Data stored in DownloadItem for drive path. | 43 // User Data stored in DownloadItem for drive path. |
38 class DriveUserData : public base::SupportsUserData::Data { | 44 class DriveUserData : public base::SupportsUserData::Data { |
39 public: | 45 public: |
40 explicit DriveUserData(const base::FilePath& path) : file_path_(path), | 46 explicit DriveUserData(const base::FilePath& path) : file_path_(path), |
41 is_complete_(false) {} | 47 is_complete_(false) {} |
42 ~DriveUserData() override {} | 48 ~DriveUserData() override {} |
43 | 49 |
44 const base::FilePath& file_path() const { return file_path_; } | 50 const base::FilePath& file_path() const { return file_path_; } |
45 const base::FilePath& cache_file_path() const { return cache_file_path_; } | 51 const base::FilePath& cache_file_path() const { return cache_file_path_; } |
46 void set_cache_file_path(const base::FilePath& path) { | 52 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 | 124 // '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. | 125 // type so that our logic can guess by its own while uploading to Drive. |
120 std::string FilterOutGenericMimeType(const std::string& mime_type) { | 126 std::string FilterOutGenericMimeType(const std::string& mime_type) { |
121 for (size_t i = 0; i < arraysize(kGenericMimeTypes); ++i) { | 127 for (size_t i = 0; i < arraysize(kGenericMimeTypes); ++i) { |
122 if (base::LowerCaseEqualsASCII(mime_type, kGenericMimeTypes[i])) | 128 if (base::LowerCaseEqualsASCII(mime_type, kGenericMimeTypes[i])) |
123 return std::string(); | 129 return std::string(); |
124 } | 130 } |
125 return mime_type; | 131 return mime_type; |
126 } | 132 } |
127 | 133 |
| 134 void IgnoreFreeDiskSpaceIfNeededForCallback(bool /*result*/) {} |
| 135 |
128 } // namespace | 136 } // namespace |
129 | 137 |
130 DownloadHandler::DownloadHandler(FileSystemInterface* file_system) | 138 DownloadHandler::DownloadHandler(FileSystemInterface* file_system) |
131 : file_system_(file_system), | 139 : file_system_(file_system), |
132 weak_ptr_factory_(this) { | 140 has_pending_free_disk_space_(false), |
133 } | 141 free_disk_space_delay_(kFreeDiskSpaceDelay), |
| 142 weak_ptr_factory_(this) {} |
134 | 143 |
135 DownloadHandler::~DownloadHandler() { | 144 DownloadHandler::~DownloadHandler() { |
136 } | 145 } |
137 | 146 |
138 // static | 147 // static |
139 DownloadHandler* DownloadHandler::GetForProfile(Profile* profile) { | 148 DownloadHandler* DownloadHandler::GetForProfile(Profile* profile) { |
140 DriveIntegrationService* service = | 149 DriveIntegrationService* service = |
141 DriveIntegrationServiceFactory::FindForProfile(profile); | 150 DriveIntegrationServiceFactory::FindForProfile(profile); |
142 if (!service || !service->IsMounted()) | 151 if (!service || !service->IsMounted()) |
143 return NULL; | 152 return NULL; |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 | 239 |
231 void DownloadHandler::CheckForFileExistence( | 240 void DownloadHandler::CheckForFileExistence( |
232 const DownloadItem* download, | 241 const DownloadItem* download, |
233 const content::CheckForFileExistenceCallback& callback) { | 242 const content::CheckForFileExistenceCallback& callback) { |
234 file_system_->GetResourceEntry( | 243 file_system_->GetResourceEntry( |
235 util::ExtractDrivePath(GetTargetPath(download)), | 244 util::ExtractDrivePath(GetTargetPath(download)), |
236 base::Bind(&ContinueCheckingForFileExistence, | 245 base::Bind(&ContinueCheckingForFileExistence, |
237 callback)); | 246 callback)); |
238 } | 247 } |
239 | 248 |
| 249 void DownloadHandler::SetFreeDiskSpaceDelayForTesting( |
| 250 const base::TimeDelta& delay) { |
| 251 free_disk_space_delay_ = delay; |
| 252 } |
| 253 |
| 254 int64 DownloadHandler::CalculateRequestSpace( |
| 255 const DownloadManager::DownloadVector& downloads) { |
| 256 int64 request_space = 0; |
| 257 |
| 258 for (const auto* download : downloads) { |
| 259 if (download->IsDone()) |
| 260 continue; |
| 261 |
| 262 const int64 total_bytes = download->GetTotalBytes(); |
| 263 // Skip unknown size download. Since drive cache tries to keep |
| 264 // drive::internal::kMinFreeSpaceInBytes, we can continue download with |
| 265 // using the space temporally. |
| 266 if (total_bytes == 0) |
| 267 continue; |
| 268 |
| 269 request_space += total_bytes - download->GetReceivedBytes(); |
| 270 } |
| 271 |
| 272 return request_space; |
| 273 } |
| 274 |
| 275 void DownloadHandler::FreeDiskSpaceIfNeeded() { |
| 276 if (has_pending_free_disk_space_) |
| 277 return; |
| 278 |
| 279 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 280 FROM_HERE, base::Bind(&DownloadHandler::FreeDiskSpaceIfNeededImmediately, |
| 281 weak_ptr_factory_.GetWeakPtr()), |
| 282 free_disk_space_delay_); |
| 283 |
| 284 has_pending_free_disk_space_ = true; |
| 285 } |
| 286 |
| 287 void DownloadHandler::FreeDiskSpaceIfNeededImmediately() { |
| 288 DownloadManager::DownloadVector downloads; |
| 289 |
| 290 // Get all downloads of current profile and its off-the-record profile. |
| 291 // TODO(yawano): support multi profiles. |
| 292 if (notifier_ && notifier_->GetManager()) { |
| 293 notifier_->GetManager()->GetAllDownloads(&downloads); |
| 294 } |
| 295 if (notifier_incognito_ && notifier_incognito_->GetManager()) { |
| 296 notifier_incognito_->GetManager()->GetAllDownloads(&downloads); |
| 297 } |
| 298 |
| 299 // Free disk space even if request size is 0 byte in order to make drive cache |
| 300 // keep drive::internal::kMinFreeSpaceInBytes. |
| 301 file_system_->FreeDiskSpaceIfNeededFor( |
| 302 CalculateRequestSpace(downloads), |
| 303 base::Bind(&IgnoreFreeDiskSpaceIfNeededForCallback)); |
| 304 |
| 305 has_pending_free_disk_space_ = false; |
| 306 } |
| 307 |
240 void DownloadHandler::OnDownloadCreated(DownloadManager* manager, | 308 void DownloadHandler::OnDownloadCreated(DownloadManager* manager, |
241 DownloadItem* download) { | 309 DownloadItem* download) { |
| 310 FreeDiskSpaceIfNeededImmediately(); |
| 311 |
242 // Remove any persisted Drive DownloadItem. crbug.com/171384 | 312 // Remove any persisted Drive DownloadItem. crbug.com/171384 |
243 if (IsPersistedDriveDownload(drive_tmp_download_path_, download)) { | 313 if (IsPersistedDriveDownload(drive_tmp_download_path_, download)) { |
244 // Remove download later, since doing it here results in a crash. | 314 // Remove download later, since doing it here results in a crash. |
245 BrowserThread::PostTask(BrowserThread::UI, | 315 BrowserThread::PostTask(BrowserThread::UI, |
246 FROM_HERE, | 316 FROM_HERE, |
247 base::Bind(&DownloadHandler::RemoveDownload, | 317 base::Bind(&DownloadHandler::RemoveDownload, |
248 weak_ptr_factory_.GetWeakPtr(), | 318 weak_ptr_factory_.GetWeakPtr(), |
249 static_cast<void*>(manager), | 319 static_cast<void*>(manager), |
250 download->GetId())); | 320 download->GetId())); |
251 } | 321 } |
252 } | 322 } |
253 | 323 |
254 void DownloadHandler::RemoveDownload(void* manager_id, int id) { | 324 void DownloadHandler::RemoveDownload(void* manager_id, int id) { |
255 DownloadManager* manager = GetDownloadManager(manager_id); | 325 DownloadManager* manager = GetDownloadManager(manager_id); |
256 if (!manager) | 326 if (!manager) |
257 return; | 327 return; |
258 DownloadItem* download = manager->GetDownload(id); | 328 DownloadItem* download = manager->GetDownload(id); |
259 if (!download) | 329 if (!download) |
260 return; | 330 return; |
261 download->Remove(); | 331 download->Remove(); |
262 } | 332 } |
263 | 333 |
264 void DownloadHandler::OnDownloadUpdated( | 334 void DownloadHandler::OnDownloadUpdated( |
265 DownloadManager* manager, DownloadItem* download) { | 335 DownloadManager* manager, DownloadItem* download) { |
266 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 336 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
267 | 337 |
| 338 FreeDiskSpaceIfNeeded(); |
| 339 |
268 // Only accept downloads that have the Drive meta data associated with them. | 340 // Only accept downloads that have the Drive meta data associated with them. |
269 DriveUserData* data = GetDriveUserData(download); | 341 DriveUserData* data = GetDriveUserData(download); |
270 if (!drive_tmp_download_path_.IsParent(download->GetTargetFilePath()) || | 342 if (!drive_tmp_download_path_.IsParent(download->GetTargetFilePath()) || |
271 !data || | 343 !data || |
272 data->is_complete()) | 344 data->is_complete()) |
273 return; | 345 return; |
274 | 346 |
275 switch (download->GetState()) { | 347 switch (download->GetState()) { |
276 case DownloadItem::IN_PROGRESS: | 348 case DownloadItem::IN_PROGRESS: |
277 break; | 349 break; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 | 419 |
348 DownloadManager* DownloadHandler::GetDownloadManager(void* manager_id) { | 420 DownloadManager* DownloadHandler::GetDownloadManager(void* manager_id) { |
349 if (manager_id == notifier_->GetManager()) | 421 if (manager_id == notifier_->GetManager()) |
350 return notifier_->GetManager(); | 422 return notifier_->GetManager(); |
351 if (notifier_incognito_ && manager_id == notifier_incognito_->GetManager()) | 423 if (notifier_incognito_ && manager_id == notifier_incognito_->GetManager()) |
352 return notifier_incognito_->GetManager(); | 424 return notifier_incognito_->GetManager(); |
353 return NULL; | 425 return NULL; |
354 } | 426 } |
355 | 427 |
356 } // namespace drive | 428 } // namespace drive |
OLD | NEW |