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 |