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_ != nullptr && notifier_->GetManager() != nullptr) { | |
hashimoto
2015/11/02 20:57:59
nit: You can write "if (notifier_ && notifier_->Ge
yawano
2015/11/05 03:51:25
Done.
| |
293 notifier_->GetManager()->GetAllDownloads(&downloads); | |
294 } | |
295 if (notifier_incognito_ != nullptr && | |
296 notifier_incognito_->GetManager() != nullptr) { | |
297 notifier_incognito_->GetManager()->GetAllDownloads(&downloads); | |
298 } | |
299 | |
300 // Free disk space even if request size is 0 byte in order to make drive cache | |
301 // keep drive::internal::kMinFreeSpaceInBytes. | |
302 file_system_->FreeDiskSpaceIfNeededFor( | |
303 CalculateRequestSpace(downloads), | |
304 base::Bind(&IgnoreFreeDiskSpaceIfNeededForCallback)); | |
305 | |
306 has_pending_free_disk_space_ = false; | |
307 } | |
308 | |
240 void DownloadHandler::OnDownloadCreated(DownloadManager* manager, | 309 void DownloadHandler::OnDownloadCreated(DownloadManager* manager, |
241 DownloadItem* download) { | 310 DownloadItem* download) { |
311 FreeDiskSpaceIfNeededImmediately(); | |
312 | |
242 // Remove any persisted Drive DownloadItem. crbug.com/171384 | 313 // Remove any persisted Drive DownloadItem. crbug.com/171384 |
243 if (IsPersistedDriveDownload(drive_tmp_download_path_, download)) { | 314 if (IsPersistedDriveDownload(drive_tmp_download_path_, download)) { |
244 // Remove download later, since doing it here results in a crash. | 315 // Remove download later, since doing it here results in a crash. |
245 BrowserThread::PostTask(BrowserThread::UI, | 316 BrowserThread::PostTask(BrowserThread::UI, |
246 FROM_HERE, | 317 FROM_HERE, |
247 base::Bind(&DownloadHandler::RemoveDownload, | 318 base::Bind(&DownloadHandler::RemoveDownload, |
248 weak_ptr_factory_.GetWeakPtr(), | 319 weak_ptr_factory_.GetWeakPtr(), |
249 static_cast<void*>(manager), | 320 static_cast<void*>(manager), |
250 download->GetId())); | 321 download->GetId())); |
251 } | 322 } |
252 } | 323 } |
253 | 324 |
254 void DownloadHandler::RemoveDownload(void* manager_id, int id) { | 325 void DownloadHandler::RemoveDownload(void* manager_id, int id) { |
255 DownloadManager* manager = GetDownloadManager(manager_id); | 326 DownloadManager* manager = GetDownloadManager(manager_id); |
256 if (!manager) | 327 if (!manager) |
257 return; | 328 return; |
258 DownloadItem* download = manager->GetDownload(id); | 329 DownloadItem* download = manager->GetDownload(id); |
259 if (!download) | 330 if (!download) |
260 return; | 331 return; |
261 download->Remove(); | 332 download->Remove(); |
262 } | 333 } |
263 | 334 |
264 void DownloadHandler::OnDownloadUpdated( | 335 void DownloadHandler::OnDownloadUpdated( |
265 DownloadManager* manager, DownloadItem* download) { | 336 DownloadManager* manager, DownloadItem* download) { |
266 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 337 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
267 | 338 |
339 FreeDiskSpaceIfNeeded(); | |
340 | |
268 // Only accept downloads that have the Drive meta data associated with them. | 341 // Only accept downloads that have the Drive meta data associated with them. |
269 DriveUserData* data = GetDriveUserData(download); | 342 DriveUserData* data = GetDriveUserData(download); |
270 if (!drive_tmp_download_path_.IsParent(download->GetTargetFilePath()) || | 343 if (!drive_tmp_download_path_.IsParent(download->GetTargetFilePath()) || |
271 !data || | 344 !data || |
272 data->is_complete()) | 345 data->is_complete()) |
273 return; | 346 return; |
274 | 347 |
275 switch (download->GetState()) { | 348 switch (download->GetState()) { |
276 case DownloadItem::IN_PROGRESS: | 349 case DownloadItem::IN_PROGRESS: |
277 break; | 350 break; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
347 | 420 |
348 DownloadManager* DownloadHandler::GetDownloadManager(void* manager_id) { | 421 DownloadManager* DownloadHandler::GetDownloadManager(void* manager_id) { |
349 if (manager_id == notifier_->GetManager()) | 422 if (manager_id == notifier_->GetManager()) |
350 return notifier_->GetManager(); | 423 return notifier_->GetManager(); |
351 if (notifier_incognito_ && manager_id == notifier_incognito_->GetManager()) | 424 if (notifier_incognito_ && manager_id == notifier_incognito_->GetManager()) |
352 return notifier_incognito_->GetManager(); | 425 return notifier_incognito_->GetManager(); |
353 return NULL; | 426 return NULL; |
354 } | 427 } |
355 | 428 |
356 } // namespace drive | 429 } // namespace drive |
OLD | NEW |