Chromium Code Reviews| 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/gdata/gdata_download_observer.h" | 5 #include "chrome/browser/chromeos/gdata/gdata_download_observer.h" |
| 6 | 6 |
| 7 #include "base/callback.h" | 7 #include "base/callback.h" |
| 8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
| 9 #include "chrome/browser/chromeos/gdata/gdata.pb.h" | 9 #include "chrome/browser/chromeos/gdata/gdata.pb.h" |
| 10 #include "chrome/browser/chromeos/gdata/gdata_documents_service.h" | 10 #include "chrome/browser/chromeos/gdata/gdata_documents_service.h" |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 23 | 23 |
| 24 namespace gdata { | 24 namespace gdata { |
| 25 namespace { | 25 namespace { |
| 26 | 26 |
| 27 // Threshold file size after which we stream the file. | 27 // Threshold file size after which we stream the file. |
| 28 const int64 kStreamingFileSize = 1 << 20; // 1MB | 28 const int64 kStreamingFileSize = 1 << 20; // 1MB |
| 29 | 29 |
| 30 // Keys for DownloadItem::ExternalData. | 30 // Keys for DownloadItem::ExternalData. |
| 31 const char kUploadingKey[] = "Uploading"; | 31 const char kUploadingKey[] = "Uploading"; |
| 32 const char kGDataPathKey[] = "GDataPath"; | 32 const char kGDataPathKey[] = "GDataPath"; |
| 33 const char kCachePathKey[] = "CachePath"; | |
| 33 | 34 |
| 34 // External Data stored in DownloadItem for ongoing uploads. | 35 // External Data stored in DownloadItem for ongoing uploads. |
| 35 class UploadingExternalData : public DownloadCompletionBlocker { | 36 class UploadingExternalData : public DownloadCompletionBlocker { |
| 36 public: | 37 public: |
| 37 UploadingExternalData(GDataUploader* uploader, int upload_id) | 38 UploadingExternalData(GDataUploader* uploader, int upload_id) |
| 38 : uploader_(uploader), | 39 : uploader_(uploader), |
| 39 upload_id_(upload_id) { | 40 upload_id_(upload_id) { |
| 40 } | 41 } |
| 41 virtual ~UploadingExternalData() {} | 42 virtual ~UploadingExternalData() {} |
| 42 | 43 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 55 public: | 56 public: |
| 56 explicit GDataExternalData(const FilePath& path) : file_path_(path) {} | 57 explicit GDataExternalData(const FilePath& path) : file_path_(path) {} |
| 57 virtual ~GDataExternalData() {} | 58 virtual ~GDataExternalData() {} |
| 58 | 59 |
| 59 const FilePath& file_path() const { return file_path_; } | 60 const FilePath& file_path() const { return file_path_; } |
| 60 | 61 |
| 61 private: | 62 private: |
| 62 FilePath file_path_; | 63 FilePath file_path_; |
| 63 }; | 64 }; |
| 64 | 65 |
| 66 // External Data stored in DownloadItem for information required to move the | |
| 67 // downloaded file to gdata cache. | |
| 68 class GDataCacheExternalData : public DownloadItem::ExternalData { | |
| 69 public: | |
| 70 explicit GDataCacheExternalData(const FilePath& virtual_dir_path, | |
| 71 const FilePath& file_content_path, | |
| 72 scoped_ptr<DocumentEntry> entry) | |
| 73 : virtual_dir_path_(virtual_dir_path), | |
| 74 file_content_path_(file_content_path), | |
| 75 entry_(entry.release()), | |
| 76 move_started_(false) { | |
| 77 } | |
| 78 virtual ~GDataCacheExternalData() {} | |
| 79 | |
| 80 const FilePath& virtual_dir_path() const { return virtual_dir_path_; } | |
| 81 const FilePath& file_content_path() const { return file_content_path_; } | |
| 82 DocumentEntry* entry() const { return entry_.get(); } | |
| 83 bool move_started() const { return move_started_; } | |
| 84 void set_move_started(bool move_started) { move_started_ = move_started; } | |
| 85 | |
| 86 private: | |
| 87 FilePath virtual_dir_path_; | |
| 88 FilePath file_content_path_; | |
| 89 scoped_ptr<DocumentEntry> entry_; | |
| 90 bool move_started_; | |
| 91 }; | |
| 92 | |
| 65 // Extracts UploadingExternalData* from |download|. | 93 // Extracts UploadingExternalData* from |download|. |
| 66 UploadingExternalData* GetUploadingExternalData(DownloadItem* download) { | 94 UploadingExternalData* GetUploadingExternalData(DownloadItem* download) { |
| 67 return static_cast<UploadingExternalData*>( | 95 return static_cast<UploadingExternalData*>( |
| 68 download->GetExternalData(&kUploadingKey)); | 96 download->GetExternalData(&kUploadingKey)); |
| 69 } | 97 } |
| 70 | 98 |
| 71 // Extracts GDataExternalData* from |download|. | 99 // Extracts GDataExternalData* from |download|. |
| 72 GDataExternalData* GetGDataExternalData(DownloadItem* download) { | 100 GDataExternalData* GetGDataExternalData(DownloadItem* download) { |
| 73 return static_cast<GDataExternalData*>( | 101 return static_cast<GDataExternalData*>( |
| 74 download->GetExternalData(&kGDataPathKey)); | 102 download->GetExternalData(&kGDataPathKey)); |
| 75 } | 103 } |
| 76 | 104 |
| 105 // Extracts GDataCacheExternalData* from |download|. | |
| 106 GDataCacheExternalData* GetGDataCacheExternalData(DownloadItem* download) { | |
| 107 return static_cast<GDataCacheExternalData*>( | |
| 108 download->GetExternalData(&kCachePathKey)); | |
| 109 } | |
| 110 | |
| 77 void RunSubstituteGDataDownloadCallback( | 111 void RunSubstituteGDataDownloadCallback( |
| 78 const GDataDownloadObserver::SubstituteGDataDownloadPathCallback& callback, | 112 const GDataDownloadObserver::SubstituteGDataDownloadPathCallback& callback, |
| 79 const FilePath* file_path) { | 113 const FilePath* file_path) { |
| 80 callback.Run(*file_path); | 114 callback.Run(*file_path); |
| 81 } | 115 } |
| 82 | 116 |
| 83 gdata::GDataSystemService* GetSystemService(Profile* profile) { | 117 gdata::GDataSystemService* GetSystemService(Profile* profile) { |
| 84 gdata::GDataSystemService* system_service = | 118 gdata::GDataSystemService* system_service = |
| 85 gdata::GDataSystemServiceFactory::GetForProfile( | 119 gdata::GDataSystemServiceFactory::GetForProfile( |
| 86 profile ? profile : ProfileManager::GetDefaultProfile()); | 120 profile ? profile : ProfileManager::GetDefaultProfile()); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 162 base::Bind(&OnEntryFound, profile, gdata_dir_path, | 196 base::Bind(&OnEntryFound, profile, gdata_dir_path, |
| 163 substitute_callback)); | 197 substitute_callback)); |
| 164 } else { | 198 } else { |
| 165 // TODO(achuith): Handle this. | 199 // TODO(achuith): Handle this. |
| 166 NOTREACHED(); | 200 NOTREACHED(); |
| 167 } | 201 } |
| 168 } | 202 } |
| 169 | 203 |
| 170 } // namespace | 204 } // namespace |
| 171 | 205 |
| 172 GDataDownloadObserver::GDataDownloadObserver() | 206 GDataDownloadObserver::GDataDownloadObserver( |
| 173 : gdata_uploader_(NULL), | 207 GDataUploader* uploader, |
| 208 GDataFileSystem* file_system) | |
| 209 : gdata_uploader_(uploader), | |
| 210 file_system_(file_system), | |
| 174 download_manager_(NULL), | 211 download_manager_(NULL), |
| 175 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { | 212 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { |
| 176 } | 213 } |
| 177 | 214 |
| 178 GDataDownloadObserver::~GDataDownloadObserver() { | 215 GDataDownloadObserver::~GDataDownloadObserver() { |
| 179 if (download_manager_) | 216 if (download_manager_) |
| 180 download_manager_->RemoveObserver(this); | 217 download_manager_->RemoveObserver(this); |
| 181 | 218 |
| 182 for (DownloadMap::iterator iter = pending_downloads_.begin(); | 219 for (DownloadMap::iterator iter = pending_downloads_.begin(); |
| 183 iter != pending_downloads_.end(); ++iter) { | 220 iter != pending_downloads_.end(); ++iter) { |
| 184 DetachFromDownload(iter->second); | 221 DetachFromDownload(iter->second); |
| 185 } | 222 } |
| 186 } | 223 } |
| 187 | 224 |
| 188 void GDataDownloadObserver::Initialize( | 225 void GDataDownloadObserver::Initialize( |
| 189 GDataUploader* gdata_uploader, | |
| 190 DownloadManager* download_manager, | 226 DownloadManager* download_manager, |
| 191 const FilePath& gdata_tmp_download_path) { | 227 const FilePath& gdata_tmp_download_path) { |
| 192 DCHECK(gdata_uploader); | |
| 193 DCHECK(!gdata_tmp_download_path.empty()); | 228 DCHECK(!gdata_tmp_download_path.empty()); |
| 194 gdata_uploader_ = gdata_uploader; | |
| 195 download_manager_ = download_manager; | 229 download_manager_ = download_manager; |
| 196 if (download_manager_) | 230 if (download_manager_) |
| 197 download_manager_->AddObserver(this); | 231 download_manager_->AddObserver(this); |
| 198 gdata_tmp_download_path_ = gdata_tmp_download_path; | 232 gdata_tmp_download_path_ = gdata_tmp_download_path; |
| 199 } | 233 } |
| 200 | 234 |
| 201 // static | 235 // static |
| 202 void GDataDownloadObserver::SubstituteGDataDownloadPath(Profile* profile, | 236 void GDataDownloadObserver::SubstituteGDataDownloadPath(Profile* profile, |
| 203 const FilePath& gdata_path, content::DownloadItem* download, | 237 const FilePath& gdata_path, content::DownloadItem* download, |
| 204 const SubstituteGDataDownloadPathCallback& callback) { | 238 const SubstituteGDataDownloadPathCallback& callback) { |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 346 | 380 |
| 347 const DownloadItem::DownloadState state = download->GetState(); | 381 const DownloadItem::DownloadState state = download->GetState(); |
| 348 switch (state) { | 382 switch (state) { |
| 349 case DownloadItem::IN_PROGRESS: | 383 case DownloadItem::IN_PROGRESS: |
| 350 AddPendingDownload(download); | 384 AddPendingDownload(download); |
| 351 UploadDownloadItem(download); | 385 UploadDownloadItem(download); |
| 352 break; | 386 break; |
| 353 | 387 |
| 354 case DownloadItem::COMPLETE: | 388 case DownloadItem::COMPLETE: |
| 355 UploadDownloadItem(download); | 389 UploadDownloadItem(download); |
| 356 RemovePendingDownload(download); | 390 MoveDownloadedFileToCache( |
| 391 download, | |
| 392 base::Bind(&GDataDownloadObserver::RemovePendingDownload, | |
| 393 weak_ptr_factory_.GetWeakPtr(), | |
| 394 download)); | |
| 357 break; | 395 break; |
| 358 | 396 |
| 359 // TODO(achuith): Stop the pending upload and delete the file. | 397 // TODO(achuith): Stop the pending upload and delete the file. |
| 360 case DownloadItem::CANCELLED: | 398 case DownloadItem::CANCELLED: |
| 361 case DownloadItem::REMOVING: | 399 case DownloadItem::REMOVING: |
| 362 case DownloadItem::INTERRUPTED: | 400 case DownloadItem::INTERRUPTED: |
| 363 RemovePendingDownload(download); | 401 RemovePendingDownload(download); |
| 364 break; | 402 break; |
| 365 | 403 |
| 366 default: | 404 default: |
| 367 NOTREACHED(); | 405 NOTREACHED(); |
| 368 } | 406 } |
| 369 DVLOG(1) << "Number of pending downloads=" << pending_downloads_.size(); | |
| 370 } | 407 } |
| 371 | 408 |
| 372 void GDataDownloadObserver::AddPendingDownload(DownloadItem* download) { | 409 void GDataDownloadObserver::AddPendingDownload(DownloadItem* download) { |
| 373 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 410 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 374 | 411 |
| 375 // Add ourself as an observer of this download if we've never seen it before. | 412 // Add ourself as an observer of this download if we've never seen it before. |
| 376 if (pending_downloads_.count(download->GetId()) == 0) { | 413 if (pending_downloads_.count(download->GetId()) == 0) { |
| 377 pending_downloads_[download->GetId()] = download; | 414 pending_downloads_[download->GetId()] = download; |
| 378 download->AddObserver(this); | 415 download->AddObserver(this); |
| 379 DVLOG(1) << "new download total bytes=" << download->GetTotalBytes() | 416 DVLOG(1) << "new download total bytes=" << download->GetTotalBytes() |
| 380 << ", full path=" << download->GetFullPath().value() | 417 << ", full path=" << download->GetFullPath().value() |
| 381 << ", mime type=" << download->GetMimeType(); | 418 << ", mime type=" << download->GetMimeType(); |
| 382 } | 419 } |
| 420 | |
| 421 DVLOG(1) << "Number of pending downloads=" << pending_downloads_.size(); | |
| 383 } | 422 } |
| 384 | 423 |
| 385 void GDataDownloadObserver::RemovePendingDownload(DownloadItem* download) { | 424 void GDataDownloadObserver::RemovePendingDownload(DownloadItem* download) { |
| 386 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 425 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 387 DCHECK(!download->IsInProgress()); | 426 DCHECK(!download->IsInProgress()); |
| 388 | 427 |
| 389 DownloadMap::iterator it = pending_downloads_.find(download->GetId()); | 428 DownloadMap::iterator it = pending_downloads_.find(download->GetId()); |
| 390 if (it != pending_downloads_.end()) { | 429 if (it != pending_downloads_.end()) { |
| 391 DetachFromDownload(download); | 430 DetachFromDownload(download); |
| 392 pending_downloads_.erase(it); | 431 pending_downloads_.erase(it); |
| 393 } | 432 } |
| 433 | |
| 434 DVLOG(1) << "Number of pending downloads=" << pending_downloads_.size(); | |
| 394 } | 435 } |
| 395 | 436 |
| 396 void GDataDownloadObserver::DetachFromDownload(DownloadItem* download) { | 437 void GDataDownloadObserver::DetachFromDownload(DownloadItem* download) { |
| 397 download->SetExternalData(&kUploadingKey, NULL); | 438 download->SetExternalData(&kUploadingKey, NULL); |
| 398 download->SetExternalData(&kGDataPathKey, NULL); | 439 download->SetExternalData(&kGDataPathKey, NULL); |
| 440 download->SetExternalData(&kCachePathKey, NULL); | |
| 399 download->RemoveObserver(this); | 441 download->RemoveObserver(this); |
| 400 } | 442 } |
| 401 | 443 |
| 402 void GDataDownloadObserver::UploadDownloadItem(DownloadItem* download) { | 444 void GDataDownloadObserver::UploadDownloadItem(DownloadItem* download) { |
| 403 // Update metadata of ongoing upload. | 445 // Update metadata of ongoing upload. |
| 404 UpdateUpload(download); | 446 UpdateUpload(download); |
| 405 | 447 |
| 406 if (!ShouldUpload(download)) | 448 if (!ShouldUpload(download)) |
| 407 return; | 449 return; |
| 408 | 450 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 467 download->GetId()); | 509 download->GetId()); |
| 468 | 510 |
| 469 return upload_file_info.Pass(); | 511 return upload_file_info.Pass(); |
| 470 } | 512 } |
| 471 | 513 |
| 472 void GDataDownloadObserver::OnUploadComplete( | 514 void GDataDownloadObserver::OnUploadComplete( |
| 473 int32 download_id, | 515 int32 download_id, |
| 474 base::PlatformFileError error, | 516 base::PlatformFileError error, |
| 475 scoped_ptr<UploadFileInfo> upload_file_info) { | 517 scoped_ptr<UploadFileInfo> upload_file_info) { |
| 476 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 518 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 519 DCHECK(upload_file_info.get()); | |
| 520 DCHECK(upload_file_info->entry.get()); | |
| 521 | |
| 477 DownloadMap::iterator iter = pending_downloads_.find(download_id); | 522 DownloadMap::iterator iter = pending_downloads_.find(download_id); |
| 478 if (iter == pending_downloads_.end()) { | 523 if (iter == pending_downloads_.end()) { |
| 479 DVLOG(1) << "Pending download not found" << download_id; | 524 DVLOG(1) << "Pending download not found" << download_id; |
| 480 return; | 525 return; |
| 481 } | 526 } |
| 482 DVLOG(1) << "Completing upload for download ID " << download_id; | 527 DVLOG(1) << "Completing upload for download ID " << download_id; |
| 483 DownloadItem* download_item = iter->second; | 528 DownloadItem* download_item = iter->second; |
| 484 UploadingExternalData* upload_data = GetUploadingExternalData(download_item); | 529 UploadingExternalData* upload_data = GetUploadingExternalData(download_item); |
| 485 DCHECK(upload_data); | 530 DCHECK(upload_data); |
| 486 upload_data->CompleteDownload(); | 531 upload_data->CompleteDownload(); |
| 532 | |
| 533 // Fill GDataCacheExternalData struct for use by MoveDownloadedFileToCache(). | |
| 534 // Note that |content_file_path| should use the final target path. | |
| 535 download_item->SetExternalData(&kCachePathKey, | |
| 536 new GDataCacheExternalData( | |
| 537 upload_file_info->gdata_path.DirName(), | |
| 538 download_item->GetTargetFilePath(), | |
|
asanka
2012/07/10 21:11:59
This doesn't affect GData uploads currently, but i
hshi1
2012/07/10 21:32:55
I see, I've moved the GetTargetFilePath() call to
| |
| 539 upload_file_info->entry.Pass())); | |
| 540 } | |
| 541 | |
| 542 void GDataDownloadObserver::MoveDownloadedFileToCache( | |
| 543 DownloadItem* download, | |
| 544 const base::Closure& callback) { | |
| 545 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 546 DCHECK(!callback.is_null()); | |
| 547 | |
| 548 GDataCacheExternalData* data = GetGDataCacheExternalData(download); | |
| 549 DCHECK(data); | |
| 550 if (data) { | |
| 551 // The observer may receive multiple COMPLETE notifications, so only | |
|
asanka
2012/07/10 21:11:59
COMPLETE is a state. So you may receive multiple O
hshi1
2012/07/10 21:32:55
Good point! Done.
On 2012/07/10 21:11:59, asanka
| |
| 552 // initiate the move if it is not already started. | |
| 553 if (!data->move_started()) { | |
| 554 // Move downloaded file to gdata cache. Remove the pending download upon | |
| 555 // comletion of the move. | |
| 556 data->set_move_started(true); | |
| 557 file_system_->AddUploadedFile(UPLOAD_NEW_FILE, | |
| 558 data->virtual_dir_path(), | |
| 559 data->entry(), | |
| 560 data->file_content_path(), | |
| 561 GDataCache::FILE_OPERATION_MOVE, | |
| 562 callback); | |
| 563 } | |
| 564 } else { | |
| 565 callback.Run(); | |
| 566 } | |
| 487 } | 567 } |
| 488 | 568 |
| 489 } // namespace gdata | 569 } // namespace gdata |
| OLD | NEW |