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 16 matching lines...) Expand all Loading... | |
| 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 | 33 |
| 34 // External Data stored in DownloadItem for ongoing uploads. | 34 // External Data stored in DownloadItem for ongoing uploads. |
| 35 class UploadingExternalData : public DownloadCompletionBlocker { | 35 class UploadingExternalData : public DownloadCompletionBlocker { |
| 36 public: | 36 public: |
| 37 UploadingExternalData(GDataUploader* uploader, int upload_id) | 37 UploadingExternalData(GDataUploader* uploader, |
| 38 int upload_id, | |
| 39 const FilePath& virtual_dir_path) | |
| 38 : uploader_(uploader), | 40 : uploader_(uploader), |
| 39 upload_id_(upload_id) { | 41 upload_id_(upload_id), |
| 42 virtual_dir_path_(virtual_dir_path) { | |
| 40 } | 43 } |
| 41 virtual ~UploadingExternalData() {} | 44 virtual ~UploadingExternalData() {} |
| 42 | 45 |
| 43 int upload_id() const { return upload_id_; } | 46 int upload_id() const { return upload_id_; } |
| 44 GDataUploader* uploader() { return uploader_; } | 47 GDataUploader* uploader() { return uploader_; } |
| 48 const FilePath& virtual_dir_path() const { return virtual_dir_path_; } | |
| 49 | |
| 50 void set_entry(scoped_ptr<DocumentEntry> entry) { entry_ = entry.Pass(); } | |
| 51 scoped_ptr<DocumentEntry> entry_passed() { return entry_.Pass(); } | |
| 45 | 52 |
| 46 private: | 53 private: |
| 47 GDataUploader* uploader_; | 54 GDataUploader* uploader_; |
| 48 int upload_id_; | 55 int upload_id_; |
| 56 FilePath virtual_dir_path_; | |
| 57 scoped_ptr<DocumentEntry> entry_; | |
| 49 | 58 |
| 50 DISALLOW_COPY_AND_ASSIGN(UploadingExternalData); | 59 DISALLOW_COPY_AND_ASSIGN(UploadingExternalData); |
| 51 }; | 60 }; |
| 52 | 61 |
| 53 // External Data stored in DownloadItem for gdata path. | 62 // External Data stored in DownloadItem for gdata path. |
| 54 class GDataExternalData : public DownloadItem::ExternalData { | 63 class GDataExternalData : public DownloadItem::ExternalData { |
| 55 public: | 64 public: |
| 56 explicit GDataExternalData(const FilePath& path) : file_path_(path) {} | 65 explicit GDataExternalData(const FilePath& path) : file_path_(path) {} |
| 57 virtual ~GDataExternalData() {} | 66 virtual ~GDataExternalData() {} |
| 58 | 67 |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 162 base::Bind(&OnEntryFound, profile, gdata_dir_path, | 171 base::Bind(&OnEntryFound, profile, gdata_dir_path, |
| 163 substitute_callback)); | 172 substitute_callback)); |
| 164 } else { | 173 } else { |
| 165 // TODO(achuith): Handle this. | 174 // TODO(achuith): Handle this. |
| 166 NOTREACHED(); | 175 NOTREACHED(); |
| 167 } | 176 } |
| 168 } | 177 } |
| 169 | 178 |
| 170 } // namespace | 179 } // namespace |
| 171 | 180 |
| 172 GDataDownloadObserver::GDataDownloadObserver() | 181 GDataDownloadObserver::GDataDownloadObserver( |
| 173 : gdata_uploader_(NULL), | 182 GDataUploader* uploader, |
| 183 GDataFileSystem* file_system) | |
| 184 : gdata_uploader_(uploader), | |
| 185 file_system_(file_system), | |
| 174 download_manager_(NULL), | 186 download_manager_(NULL), |
| 175 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { | 187 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { |
| 176 } | 188 } |
| 177 | 189 |
| 178 GDataDownloadObserver::~GDataDownloadObserver() { | 190 GDataDownloadObserver::~GDataDownloadObserver() { |
| 179 if (download_manager_) | 191 if (download_manager_) |
| 180 download_manager_->RemoveObserver(this); | 192 download_manager_->RemoveObserver(this); |
| 181 | 193 |
| 182 for (DownloadMap::iterator iter = pending_downloads_.begin(); | 194 for (DownloadMap::iterator iter = pending_downloads_.begin(); |
| 183 iter != pending_downloads_.end(); ++iter) { | 195 iter != pending_downloads_.end(); ++iter) { |
| 184 DetachFromDownload(iter->second); | 196 DetachFromDownload(iter->second); |
| 185 } | 197 } |
| 186 } | 198 } |
| 187 | 199 |
| 188 void GDataDownloadObserver::Initialize( | 200 void GDataDownloadObserver::Initialize( |
| 189 GDataUploader* gdata_uploader, | |
| 190 DownloadManager* download_manager, | 201 DownloadManager* download_manager, |
| 191 const FilePath& gdata_tmp_download_path) { | 202 const FilePath& gdata_tmp_download_path) { |
| 192 DCHECK(gdata_uploader); | |
| 193 DCHECK(!gdata_tmp_download_path.empty()); | 203 DCHECK(!gdata_tmp_download_path.empty()); |
| 194 gdata_uploader_ = gdata_uploader; | |
| 195 download_manager_ = download_manager; | 204 download_manager_ = download_manager; |
| 196 if (download_manager_) | 205 if (download_manager_) |
| 197 download_manager_->AddObserver(this); | 206 download_manager_->AddObserver(this); |
| 198 gdata_tmp_download_path_ = gdata_tmp_download_path; | 207 gdata_tmp_download_path_ = gdata_tmp_download_path; |
| 199 } | 208 } |
| 200 | 209 |
| 201 // static | 210 // static |
| 202 void GDataDownloadObserver::SubstituteGDataDownloadPath(Profile* profile, | 211 void GDataDownloadObserver::SubstituteGDataDownloadPath(Profile* profile, |
| 203 const FilePath& gdata_path, content::DownloadItem* download, | 212 const FilePath& gdata_path, content::DownloadItem* download, |
| 204 const SubstituteGDataDownloadPathCallback& callback) { | 213 const SubstituteGDataDownloadPathCallback& callback) { |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 346 | 355 |
| 347 const DownloadItem::DownloadState state = download->GetState(); | 356 const DownloadItem::DownloadState state = download->GetState(); |
| 348 switch (state) { | 357 switch (state) { |
| 349 case DownloadItem::IN_PROGRESS: | 358 case DownloadItem::IN_PROGRESS: |
| 350 AddPendingDownload(download); | 359 AddPendingDownload(download); |
| 351 UploadDownloadItem(download); | 360 UploadDownloadItem(download); |
| 352 break; | 361 break; |
| 353 | 362 |
| 354 case DownloadItem::COMPLETE: | 363 case DownloadItem::COMPLETE: |
| 355 UploadDownloadItem(download); | 364 UploadDownloadItem(download); |
| 365 MoveFileToGDataCache(download); | |
| 356 RemovePendingDownload(download); | 366 RemovePendingDownload(download); |
| 357 break; | 367 break; |
| 358 | 368 |
| 359 // TODO(achuith): Stop the pending upload and delete the file. | 369 // TODO(achuith): Stop the pending upload and delete the file. |
| 360 case DownloadItem::CANCELLED: | 370 case DownloadItem::CANCELLED: |
| 361 case DownloadItem::REMOVING: | 371 case DownloadItem::REMOVING: |
| 362 case DownloadItem::INTERRUPTED: | 372 case DownloadItem::INTERRUPTED: |
| 363 RemovePendingDownload(download); | 373 RemovePendingDownload(download); |
| 364 break; | 374 break; |
| 365 | 375 |
| 366 default: | 376 default: |
| 367 NOTREACHED(); | 377 NOTREACHED(); |
| 368 } | 378 } |
| 379 | |
| 369 DVLOG(1) << "Number of pending downloads=" << pending_downloads_.size(); | 380 DVLOG(1) << "Number of pending downloads=" << pending_downloads_.size(); |
| 370 } | 381 } |
| 371 | 382 |
| 372 void GDataDownloadObserver::AddPendingDownload(DownloadItem* download) { | 383 void GDataDownloadObserver::AddPendingDownload(DownloadItem* download) { |
| 373 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 384 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 374 | 385 |
| 375 // Add ourself as an observer of this download if we've never seen it before. | 386 // Add ourself as an observer of this download if we've never seen it before. |
| 376 if (pending_downloads_.count(download->GetId()) == 0) { | 387 if (pending_downloads_.count(download->GetId()) == 0) { |
| 377 pending_downloads_[download->GetId()] = download; | 388 pending_downloads_[download->GetId()] = download; |
| 378 download->AddObserver(this); | 389 download->AddObserver(this); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 400 } | 411 } |
| 401 | 412 |
| 402 void GDataDownloadObserver::UploadDownloadItem(DownloadItem* download) { | 413 void GDataDownloadObserver::UploadDownloadItem(DownloadItem* download) { |
| 403 // Update metadata of ongoing upload. | 414 // Update metadata of ongoing upload. |
| 404 UpdateUpload(download); | 415 UpdateUpload(download); |
| 405 | 416 |
| 406 if (!ShouldUpload(download)) | 417 if (!ShouldUpload(download)) |
| 407 return; | 418 return; |
| 408 | 419 |
| 409 scoped_ptr<UploadFileInfo> upload_file_info = CreateUploadFileInfo(download); | 420 scoped_ptr<UploadFileInfo> upload_file_info = CreateUploadFileInfo(download); |
| 421 const FilePath& virtual_dir_path = upload_file_info->gdata_path.DirName(); | |
| 410 const int upload_id = gdata_uploader_->UploadNewFile( | 422 const int upload_id = gdata_uploader_->UploadNewFile( |
| 411 upload_file_info.Pass()); | 423 upload_file_info.Pass()); |
| 412 | 424 |
| 413 // TODO(achuith): Fix this. | 425 // TODO(achuith): Fix this. |
| 414 // We won't know the upload ID until the after the | 426 // We won't know the upload ID until the after the |
| 415 // GDataUploader::UploadNewFile() call. | 427 // GDataUploader::UploadNewFile() call. |
| 416 download->SetExternalData(&kUploadingKey, | 428 download->SetExternalData(&kUploadingKey, |
| 417 new UploadingExternalData(gdata_uploader_, upload_id)); | 429 new UploadingExternalData(gdata_uploader_, upload_id, virtual_dir_path)); |
| 418 } | 430 } |
| 419 | 431 |
| 420 void GDataDownloadObserver::UpdateUpload(DownloadItem* download) { | 432 void GDataDownloadObserver::UpdateUpload(DownloadItem* download) { |
| 421 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 433 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 422 | 434 |
| 423 UploadingExternalData* upload_data = GetUploadingExternalData(download); | 435 UploadingExternalData* upload_data = GetUploadingExternalData(download); |
| 424 if (!upload_data) { | 436 if (!upload_data) { |
| 425 DVLOG(1) << "No UploadingExternalData for download " << download->GetId(); | 437 DVLOG(1) << "No UploadingExternalData for download " << download->GetId(); |
| 426 return; | 438 return; |
| 427 } | 439 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 467 download->GetId()); | 479 download->GetId()); |
| 468 | 480 |
| 469 return upload_file_info.Pass(); | 481 return upload_file_info.Pass(); |
| 470 } | 482 } |
| 471 | 483 |
| 472 void GDataDownloadObserver::OnUploadComplete( | 484 void GDataDownloadObserver::OnUploadComplete( |
| 473 int32 download_id, | 485 int32 download_id, |
| 474 base::PlatformFileError error, | 486 base::PlatformFileError error, |
| 475 scoped_ptr<UploadFileInfo> upload_file_info) { | 487 scoped_ptr<UploadFileInfo> upload_file_info) { |
| 476 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 488 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 489 DCHECK(upload_file_info.get()); | |
| 490 DCHECK(upload_file_info->entry.get()); | |
| 491 | |
| 492 // Look up the DownloadItem for the |download_id|. | |
| 477 DownloadMap::iterator iter = pending_downloads_.find(download_id); | 493 DownloadMap::iterator iter = pending_downloads_.find(download_id); |
| 478 if (iter == pending_downloads_.end()) { | 494 if (iter == pending_downloads_.end()) { |
| 479 DVLOG(1) << "Pending download not found" << download_id; | 495 DVLOG(1) << "Pending download not found" << download_id; |
| 480 return; | 496 return; |
| 481 } | 497 } |
| 482 DVLOG(1) << "Completing upload for download ID " << download_id; | 498 DVLOG(1) << "Completing upload for download ID " << download_id; |
| 483 DownloadItem* download_item = iter->second; | 499 DownloadItem* download_item = iter->second; |
| 500 | |
| 484 UploadingExternalData* upload_data = GetUploadingExternalData(download_item); | 501 UploadingExternalData* upload_data = GetUploadingExternalData(download_item); |
| 485 DCHECK(upload_data); | 502 DCHECK(upload_data); |
| 503 | |
| 504 // Take ownership of the DocumentEntry from UploadFileInfo. This is used by | |
| 505 // GDataFileSystem::AddUploadedFile() to add the entry to GDataCache after the | |
| 506 // upload completes. | |
| 507 upload_data->set_entry(upload_file_info->entry.Pass()); | |
| 508 | |
| 509 // Allow the download item to complete. | |
| 486 upload_data->CompleteDownload(); | 510 upload_data->CompleteDownload(); |
| 487 } | 511 } |
| 488 | 512 |
| 513 void GDataDownloadObserver::MoveFileToGDataCache(DownloadItem* download) { | |
| 514 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 515 | |
| 516 UploadingExternalData* data = GetUploadingExternalData(download); | |
| 517 if (!data) { | |
| 518 NOTREACHED(); | |
| 519 return; | |
| 520 } | |
| 521 | |
| 522 // Take ownership of the DocumentEntry object. It will be released upon | |
| 523 // completion of the AddUploadedFile() call below. | |
|
asanka
2012/07/11 15:56:52
Is it? It looks like |entry| will leak.
hshi1
2012/07/11 16:17:40
It won't leak. Upon completion of the AddUploadedF
asanka
2012/07/11 16:31:37
Ah. Sorry. You are right.
| |
| 524 DocumentEntry* entry = data->entry_passed().release(); | |
| 525 if (!entry) { | |
| 526 NOTREACHED(); | |
| 527 return; | |
| 528 } | |
| 529 | |
| 530 // Move downloaded file to gdata cache. Note that |content_file_path| should | |
| 531 // use the final target path when the download item is in COMPLETE state. | |
| 532 file_system_->AddUploadedFile(UPLOAD_NEW_FILE, | |
| 533 data->virtual_dir_path(), | |
| 534 entry, | |
| 535 download->GetTargetFilePath(), | |
| 536 GDataCache::FILE_OPERATION_MOVE, | |
| 537 base::Bind(&base::DeletePointer<DocumentEntry>, | |
| 538 entry)); | |
| 539 } | |
| 540 | |
| 489 } // namespace gdata | 541 } // namespace gdata |
| OLD | NEW |