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/extensions/api/downloads/downloads_api.h" | 5 #include "chrome/browser/extensions/api/downloads/downloads_api.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cctype> | 8 #include <cctype> |
| 9 #include <iterator> | 9 #include <iterator> |
| 10 #include <set> | 10 #include <set> |
| 11 #include <string> | 11 #include <string> |
| 12 | 12 |
| 13 #include "base/basictypes.h" | 13 #include "base/basictypes.h" |
| 14 #include "base/bind.h" | 14 #include "base/bind.h" |
| 15 #include "base/bind_helpers.h" | 15 #include "base/bind_helpers.h" |
| 16 #include "base/callback.h" | 16 #include "base/callback.h" |
| 17 #include "base/file_path.h" | |
| 17 #include "base/json/json_writer.h" | 18 #include "base/json/json_writer.h" |
| 18 #include "base/lazy_instance.h" | 19 #include "base/lazy_instance.h" |
| 19 #include "base/logging.h" | 20 #include "base/logging.h" |
| 20 #include "base/metrics/histogram.h" | 21 #include "base/metrics/histogram.h" |
| 21 #include "base/stl_util.h" | 22 #include "base/stl_util.h" |
| 22 #include "base/string16.h" | 23 #include "base/string16.h" |
| 23 #include "base/string_split.h" | 24 #include "base/string_split.h" |
| 24 #include "base/string_util.h" | 25 #include "base/string_util.h" |
| 25 #include "base/stringprintf.h" | 26 #include "base/stringprintf.h" |
| 26 #include "base/values.h" | 27 #include "base/values.h" |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 173 | 174 |
| 174 DownloadItem::DownloadState StateEnumFromString(const std::string& state) { | 175 DownloadItem::DownloadState StateEnumFromString(const std::string& state) { |
| 175 for (size_t i = 0; i < arraysize(kStateStrings); ++i) { | 176 for (size_t i = 0; i < arraysize(kStateStrings); ++i) { |
| 176 if ((kStateStrings[i] != NULL) && (state == kStateStrings[i])) | 177 if ((kStateStrings[i] != NULL) && (state == kStateStrings[i])) |
| 177 return static_cast<DownloadItem::DownloadState>(i); | 178 return static_cast<DownloadItem::DownloadState>(i); |
| 178 } | 179 } |
| 179 return DownloadItem::MAX_DOWNLOAD_STATE; | 180 return DownloadItem::MAX_DOWNLOAD_STATE; |
| 180 } | 181 } |
| 181 | 182 |
| 182 bool ValidateFilename(const string16& filename) { | 183 bool ValidateFilename(const string16& filename) { |
| 183 // TODO(benjhayden): More robust validation of filename. | 184 if (filename.empty() || |
| 184 if ((filename.find('/') != string16::npos) || | 185 (filename.find('/') != string16::npos) || |
| 185 (filename.find('\\') != string16::npos)) | 186 (filename.find('\\') != string16::npos)) |
| 186 return false; | 187 return false; |
| 187 if (filename.size() >= 2u && filename[0] == L'.' && filename[1] == L'.') | 188 if ((filename.size() >= 2u) && |
| 189 (filename[0] == L'.') && | |
| 190 (filename[1] == L'.')) | |
|
Randy Smith (Not in Mondays)
2013/01/14 21:02:29
Doesn't this allow for, e.g. "phantom_subdir/../..
benjhayden
2013/01/17 02:52:05
Yep, changed it to FilePath::ReferencesParent.
| |
| 188 return false; | 191 return false; |
| 189 return true; | 192 return true; |
| 190 } | 193 } |
| 191 | 194 |
| 192 std::string TimeToISO8601(const base::Time& t) { | 195 std::string TimeToISO8601(const base::Time& t) { |
| 193 base::Time::Exploded exploded; | 196 base::Time::Exploded exploded; |
| 194 t.UTCExplode(&exploded); | 197 t.UTCExplode(&exploded); |
| 195 return base::StringPrintf( | 198 return base::StringPrintf( |
| 196 "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", exploded.year, exploded.month, | 199 "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", exploded.year, exploded.month, |
| 197 exploded.day_of_month, exploded.hour, exploded.minute, exploded.second, | 200 exploded.day_of_month, exploded.hour, exploded.minute, exploded.second, |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 251 }; | 254 }; |
| 252 | 255 |
| 253 bool DownloadFileIconExtractorImpl::ExtractIconURLForPath( | 256 bool DownloadFileIconExtractorImpl::ExtractIconURLForPath( |
| 254 const FilePath& path, | 257 const FilePath& path, |
| 255 IconLoader::IconSize icon_size, | 258 IconLoader::IconSize icon_size, |
| 256 IconURLCallback callback) { | 259 IconURLCallback callback) { |
| 257 callback_ = callback; | 260 callback_ = callback; |
| 258 IconManager* im = g_browser_process->icon_manager(); | 261 IconManager* im = g_browser_process->icon_manager(); |
| 259 // The contents of the file at |path| may have changed since a previous | 262 // The contents of the file at |path| may have changed since a previous |
| 260 // request, in which case the associated icon may also have changed. | 263 // request, in which case the associated icon may also have changed. |
| 261 // Therefore, for the moment we always call LoadIcon instead of attempting | 264 // Therefore, always call LoadIcon instead of attempting a LookupIcon. |
| 262 // a LookupIcon. | |
| 263 im->LoadIcon(path, | 265 im->LoadIcon(path, |
| 264 icon_size, | 266 icon_size, |
| 265 base::Bind(&DownloadFileIconExtractorImpl::OnIconLoadComplete, | 267 base::Bind(&DownloadFileIconExtractorImpl::OnIconLoadComplete, |
| 266 base::Unretained(this)), | 268 base::Unretained(this)), |
| 267 &cancelable_task_tracker_); | 269 &cancelable_task_tracker_); |
| 268 return true; | 270 return true; |
| 269 } | 271 } |
| 270 | 272 |
| 271 void DownloadFileIconExtractorImpl::OnIconLoadComplete(gfx::Image* icon) { | 273 void DownloadFileIconExtractorImpl::OnIconLoadComplete(gfx::Image* icon) { |
| 272 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 274 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 398 // TODO(benjhayden): Consider switching from LazyInstance to explicit string | 400 // TODO(benjhayden): Consider switching from LazyInstance to explicit string |
| 399 // comparisons. | 401 // comparisons. |
| 400 static base::LazyInstance<SortTypeMap> sorter_types = | 402 static base::LazyInstance<SortTypeMap> sorter_types = |
| 401 LAZY_INSTANCE_INITIALIZER; | 403 LAZY_INSTANCE_INITIALIZER; |
| 402 if (sorter_types.Get().size() == 0) | 404 if (sorter_types.Get().size() == 0) |
| 403 InitSortTypeMap(sorter_types.Get()); | 405 InitSortTypeMap(sorter_types.Get()); |
| 404 | 406 |
| 405 std::vector<std::string> order_by_strs; | 407 std::vector<std::string> order_by_strs; |
| 406 base::SplitString(order_by_str, ' ', &order_by_strs); | 408 base::SplitString(order_by_str, ' ', &order_by_strs); |
| 407 for (std::vector<std::string>::const_iterator iter = order_by_strs.begin(); | 409 for (std::vector<std::string>::const_iterator iter = order_by_strs.begin(); |
| 408 iter != order_by_strs.end(); ++iter) { | 410 iter != order_by_strs.end(); ++iter) { |
| 409 std::string term_str = *iter; | 411 std::string term_str = *iter; |
| 410 if (term_str.empty()) | 412 if (term_str.empty()) |
| 411 continue; | 413 continue; |
| 412 DownloadQuery::SortDirection direction = DownloadQuery::ASCENDING; | 414 DownloadQuery::SortDirection direction = DownloadQuery::ASCENDING; |
| 413 if (term_str[0] == '-') { | 415 if (term_str[0] == '-') { |
| 414 direction = DownloadQuery::DESCENDING; | 416 direction = DownloadQuery::DESCENDING; |
| 415 term_str = term_str.substr(1); | 417 term_str = term_str.substr(1); |
| 416 } | 418 } |
| 417 SortTypeMap::const_iterator sorter_type = | 419 SortTypeMap::const_iterator sorter_type = |
| 418 sorter_types.Get().find(term_str); | 420 sorter_types.Get().find(term_str); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 533 base::SupportsUserData::Data* data = download_item->GetUserData(kKey); | 535 base::SupportsUserData::Data* data = download_item->GetUserData(kKey); |
| 534 return (data == NULL) ? NULL : | 536 return (data == NULL) ? NULL : |
| 535 static_cast<ExtensionDownloadsEventRouterData*>(data); | 537 static_cast<ExtensionDownloadsEventRouterData*>(data); |
| 536 } | 538 } |
| 537 | 539 |
| 538 explicit ExtensionDownloadsEventRouterData( | 540 explicit ExtensionDownloadsEventRouterData( |
| 539 DownloadItem* download_item, | 541 DownloadItem* download_item, |
| 540 scoped_ptr<base::DictionaryValue> json_item) | 542 scoped_ptr<base::DictionaryValue> json_item) |
| 541 : updated_(0), | 543 : updated_(0), |
| 542 changed_fired_(0), | 544 changed_fired_(0), |
| 543 json_(json_item.Pass()) { | 545 json_(json_item.Pass()), |
| 546 determiner_index_(-1), | |
| 547 determined_overwrite_(false) { | |
| 544 download_item->SetUserData(kKey, this); | 548 download_item->SetUserData(kKey, this); |
| 545 } | 549 } |
| 546 | 550 |
| 547 virtual ~ExtensionDownloadsEventRouterData() { | 551 virtual ~ExtensionDownloadsEventRouterData() { |
| 548 if (updated_ > 0) { | 552 if (updated_ > 0) { |
| 549 UMA_HISTOGRAM_PERCENTAGE("Download.OnChanged", | 553 UMA_HISTOGRAM_PERCENTAGE("Download.OnChanged", |
| 550 (changed_fired_ * 100 / updated_)); | 554 (changed_fired_ * 100 / updated_)); |
| 551 } | 555 } |
| 552 } | 556 } |
| 553 | 557 |
| 554 const base::DictionaryValue& json() const { return *json_.get(); } | 558 const base::DictionaryValue& json() const { return *json_.get(); } |
| 555 void set_json(scoped_ptr<base::DictionaryValue> json_item) { | 559 void set_json(scoped_ptr<base::DictionaryValue> json_item) { |
| 556 json_ = json_item.Pass(); | 560 json_ = json_item.Pass(); |
| 557 } | 561 } |
| 558 | 562 |
| 559 void OnItemUpdated() { ++updated_; } | 563 void OnItemUpdated() { ++updated_; } |
| 560 void OnChangedFired() { ++changed_fired_; } | 564 void OnChangedFired() { ++changed_fired_; } |
| 561 | 565 |
| 566 void set_filename_change_callbacks( | |
| 567 const base::Closure& no_change, | |
| 568 const ExtensionDownloadsEventRouter::FilenameChangedCallback& change) { | |
| 569 filename_no_change_ = no_change; | |
| 570 filename_change_ = change; | |
| 571 } | |
| 572 | |
| 573 void AddPendingDeterminer(const std::string& extension_id, | |
| 574 const std::string& sub_event_id) { | |
| 575 determiners_.push_back(DeterminerInfo(extension_id, sub_event_id)); | |
| 576 } | |
| 577 | |
| 578 bool DeterminerCallback( | |
| 579 const std::string& extension_id, | |
| 580 const std::string& sub_event_id, | |
| 581 const FilePath& filename, | |
| 582 bool overwrite) { | |
|
Randy Smith (Not in Mondays)
2013/01/14 21:02:29
How likely is it that we'll get a response we didn
benjhayden
2013/01/17 02:52:05
AFAIU, it should be impossible to receive an unexp
| |
| 583 bool found_info = false; | |
| 584 for (int index = 0; index < static_cast<int>(determiners_.size()); | |
| 585 ++index) { | |
| 586 if ((determiners_[index].extension_id == extension_id) && | |
| 587 (determiners_[index].sub_event_id == sub_event_id)) { | |
| 588 DCHECK(!determiners_[index].reported); | |
| 589 determiners_[index].reported = true; | |
| 590 found_info = true; | |
| 591 if (!filename.empty() && | |
| 592 !filename.IsAbsolute() && | |
| 593 (index > determiner_index_)) { | |
| 594 determined_filename_ = filename; | |
| 595 determined_overwrite_ = overwrite; | |
| 596 determiner_index_ = index; | |
| 597 } | |
| 598 } | |
| 599 } | |
| 600 if (!found_info) | |
| 601 return false; | |
| 602 for (size_t index = 0; index < determiners_.size(); ++index) { | |
| 603 if (!determiners_[index].reported) | |
| 604 return true; | |
| 605 } | |
| 606 determiners_.clear(); | |
| 607 if (determined_filename_.empty()) { | |
| 608 filename_no_change_.Run(); | |
| 609 } else { | |
| 610 filename_change_.Run(determined_filename_, determined_overwrite_); | |
| 611 } | |
| 612 return true; | |
| 613 } | |
| 614 | |
| 562 private: | 615 private: |
| 616 struct DeterminerInfo { | |
| 617 DeterminerInfo(const std::string& e_id, const std::string& sub_id); | |
| 618 ~DeterminerInfo(); | |
| 619 | |
| 620 std::string extension_id; | |
| 621 std::string sub_event_id; | |
| 622 bool reported; | |
| 623 }; | |
| 624 typedef std::vector<DeterminerInfo> DeterminerInfoVector; | |
| 625 | |
| 563 static const char kKey[]; | 626 static const char kKey[]; |
| 564 | 627 |
| 565 int updated_; | 628 int updated_; |
| 566 int changed_fired_; | 629 int changed_fired_; |
| 567 scoped_ptr<base::DictionaryValue> json_; | 630 scoped_ptr<base::DictionaryValue> json_; |
| 631 base::Closure filename_no_change_; | |
| 632 ExtensionDownloadsEventRouter::FilenameChangedCallback filename_change_; | |
| 633 DeterminerInfoVector determiners_; | |
| 634 int determiner_index_; | |
| 635 FilePath determined_filename_; | |
| 636 bool determined_overwrite_; | |
| 568 | 637 |
| 569 DISALLOW_COPY_AND_ASSIGN(ExtensionDownloadsEventRouterData); | 638 DISALLOW_COPY_AND_ASSIGN(ExtensionDownloadsEventRouterData); |
| 570 }; | 639 }; |
| 571 | 640 |
| 641 ExtensionDownloadsEventRouterData::DeterminerInfo::DeterminerInfo( | |
| 642 const std::string& e_id, const std::string& sub_id) | |
| 643 : extension_id(e_id), sub_event_id(sub_id) { | |
| 644 } | |
| 645 | |
| 646 ExtensionDownloadsEventRouterData::DeterminerInfo::~DeterminerInfo() {} | |
| 647 | |
| 572 const char ExtensionDownloadsEventRouterData::kKey[] = | 648 const char ExtensionDownloadsEventRouterData::kKey[] = |
| 573 "DownloadItem ExtensionDownloadsEventRouterData"; | 649 "DownloadItem ExtensionDownloadsEventRouterData"; |
| 574 | 650 |
| 575 class ManagerDestructionObserver : public DownloadManager::Observer { | 651 class ManagerDestructionObserver : public DownloadManager::Observer { |
| 576 public: | 652 public: |
| 577 static void CheckForHistoryFilesRemoval(DownloadManager* manager) { | 653 static void CheckForHistoryFilesRemoval(DownloadManager* manager) { |
| 578 if (!manager) | 654 if (!manager) |
| 579 return; | 655 return; |
| 580 if (!manager_file_existence_last_checked_) | 656 if (!manager_file_existence_last_checked_) |
| 581 manager_file_existence_last_checked_ = | 657 manager_file_existence_last_checked_ = |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 624 | 700 |
| 625 DISALLOW_COPY_AND_ASSIGN(ManagerDestructionObserver); | 701 DISALLOW_COPY_AND_ASSIGN(ManagerDestructionObserver); |
| 626 }; | 702 }; |
| 627 | 703 |
| 628 std::map<DownloadManager*, ManagerDestructionObserver*>* | 704 std::map<DownloadManager*, ManagerDestructionObserver*>* |
| 629 ManagerDestructionObserver::manager_file_existence_last_checked_ = NULL; | 705 ManagerDestructionObserver::manager_file_existence_last_checked_ = NULL; |
| 630 | 706 |
| 631 } // namespace | 707 } // namespace |
| 632 | 708 |
| 633 DownloadsDownloadFunction::DownloadsDownloadFunction() {} | 709 DownloadsDownloadFunction::DownloadsDownloadFunction() {} |
| 710 | |
| 634 DownloadsDownloadFunction::~DownloadsDownloadFunction() {} | 711 DownloadsDownloadFunction::~DownloadsDownloadFunction() {} |
| 635 | 712 |
| 636 bool DownloadsDownloadFunction::RunImpl() { | 713 bool DownloadsDownloadFunction::RunImpl() { |
| 637 scoped_ptr<extensions::api::downloads::Download::Params> params( | 714 scoped_ptr<extensions::api::downloads::Download::Params> params( |
| 638 extensions::api::downloads::Download::Params::Create(*args_)); | 715 extensions::api::downloads::Download::Params::Create(*args_)); |
| 639 EXTENSION_FUNCTION_VALIDATE(params.get()); | 716 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 640 const extensions::api::downloads::DownloadOptions& options = params->options; | 717 const extensions::api::downloads::DownloadOptions& options = params->options; |
| 641 GURL download_url(options.url); | 718 GURL download_url(options.url); |
| 642 if (!download_url.is_valid() || | 719 if (!download_url.is_valid() || |
| 643 (!download_url.SchemeIs("data") && | 720 (!download_url.SchemeIs("data") && |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 720 DCHECK_EQ(net::OK, error); | 797 DCHECK_EQ(net::OK, error); |
| 721 SetResult(base::Value::CreateIntegerValue(item->GetId())); | 798 SetResult(base::Value::CreateIntegerValue(item->GetId())); |
| 722 } else { | 799 } else { |
| 723 DCHECK_NE(net::OK, error); | 800 DCHECK_NE(net::OK, error); |
| 724 error_ = net::ErrorToString(error); | 801 error_ = net::ErrorToString(error); |
| 725 } | 802 } |
| 726 SendResponse(error_.empty()); | 803 SendResponse(error_.empty()); |
| 727 } | 804 } |
| 728 | 805 |
| 729 DownloadsSearchFunction::DownloadsSearchFunction() {} | 806 DownloadsSearchFunction::DownloadsSearchFunction() {} |
| 807 | |
| 730 DownloadsSearchFunction::~DownloadsSearchFunction() {} | 808 DownloadsSearchFunction::~DownloadsSearchFunction() {} |
| 731 | 809 |
| 732 bool DownloadsSearchFunction::RunImpl() { | 810 bool DownloadsSearchFunction::RunImpl() { |
| 733 scoped_ptr<extensions::api::downloads::Search::Params> params( | 811 scoped_ptr<extensions::api::downloads::Search::Params> params( |
| 734 extensions::api::downloads::Search::Params::Create(*args_)); | 812 extensions::api::downloads::Search::Params::Create(*args_)); |
| 735 EXTENSION_FUNCTION_VALIDATE(params.get()); | 813 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 736 DownloadManager* manager = NULL; | 814 DownloadManager* manager = NULL; |
| 737 DownloadManager* incognito_manager = NULL; | 815 DownloadManager* incognito_manager = NULL; |
| 738 GetManagers(profile(), include_incognito(), &manager, &incognito_manager); | 816 GetManagers(profile(), include_incognito(), &manager, &incognito_manager); |
| 739 ManagerDestructionObserver::CheckForHistoryFilesRemoval(manager); | 817 ManagerDestructionObserver::CheckForHistoryFilesRemoval(manager); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 757 scoped_ptr<base::DictionaryValue> json_item(DownloadItemToJSON( | 835 scoped_ptr<base::DictionaryValue> json_item(DownloadItemToJSON( |
| 758 *it, off_record)); | 836 *it, off_record)); |
| 759 json_results->Append(json_item.release()); | 837 json_results->Append(json_item.release()); |
| 760 } | 838 } |
| 761 SetResult(json_results); | 839 SetResult(json_results); |
| 762 RecordApiFunctions(DOWNLOADS_FUNCTION_SEARCH); | 840 RecordApiFunctions(DOWNLOADS_FUNCTION_SEARCH); |
| 763 return true; | 841 return true; |
| 764 } | 842 } |
| 765 | 843 |
| 766 DownloadsPauseFunction::DownloadsPauseFunction() {} | 844 DownloadsPauseFunction::DownloadsPauseFunction() {} |
| 845 | |
| 767 DownloadsPauseFunction::~DownloadsPauseFunction() {} | 846 DownloadsPauseFunction::~DownloadsPauseFunction() {} |
| 768 | 847 |
| 769 bool DownloadsPauseFunction::RunImpl() { | 848 bool DownloadsPauseFunction::RunImpl() { |
| 770 scoped_ptr<extensions::api::downloads::Pause::Params> params( | 849 scoped_ptr<extensions::api::downloads::Pause::Params> params( |
| 771 extensions::api::downloads::Pause::Params::Create(*args_)); | 850 extensions::api::downloads::Pause::Params::Create(*args_)); |
| 772 EXTENSION_FUNCTION_VALIDATE(params.get()); | 851 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 773 DownloadItem* download_item = GetDownloadIfInProgress( | 852 DownloadItem* download_item = GetDownloadIfInProgress( |
| 774 profile(), include_incognito(), params->download_id); | 853 profile(), include_incognito(), params->download_id); |
| 775 if (download_item == NULL) { | 854 if (download_item == NULL) { |
| 776 // This could be due to an invalid download ID, or it could be due to the | 855 // This could be due to an invalid download ID, or it could be due to the |
| 777 // download not being currently active. | 856 // download not being currently active. |
| 778 error_ = download_extension_errors::kInvalidOperationError; | 857 error_ = download_extension_errors::kInvalidOperationError; |
| 779 } else { | 858 } else { |
| 780 // If the item is already paused, this is a no-op and the | 859 // If the item is already paused, this is a no-op and the |
| 781 // operation will silently succeed. | 860 // operation will silently succeed. |
| 782 download_item->Pause(); | 861 download_item->Pause(); |
| 783 } | 862 } |
| 784 if (error_.empty()) | 863 if (error_.empty()) |
| 785 RecordApiFunctions(DOWNLOADS_FUNCTION_PAUSE); | 864 RecordApiFunctions(DOWNLOADS_FUNCTION_PAUSE); |
| 786 return error_.empty(); | 865 return error_.empty(); |
| 787 } | 866 } |
| 788 | 867 |
| 789 DownloadsResumeFunction::DownloadsResumeFunction() {} | 868 DownloadsResumeFunction::DownloadsResumeFunction() {} |
| 869 | |
| 790 DownloadsResumeFunction::~DownloadsResumeFunction() {} | 870 DownloadsResumeFunction::~DownloadsResumeFunction() {} |
| 791 | 871 |
| 792 bool DownloadsResumeFunction::RunImpl() { | 872 bool DownloadsResumeFunction::RunImpl() { |
| 793 scoped_ptr<extensions::api::downloads::Resume::Params> params( | 873 scoped_ptr<extensions::api::downloads::Resume::Params> params( |
| 794 extensions::api::downloads::Resume::Params::Create(*args_)); | 874 extensions::api::downloads::Resume::Params::Create(*args_)); |
| 795 EXTENSION_FUNCTION_VALIDATE(params.get()); | 875 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 796 DownloadItem* download_item = GetDownloadIfInProgress( | 876 DownloadItem* download_item = GetDownloadIfInProgress( |
| 797 profile(), include_incognito(), params->download_id); | 877 profile(), include_incognito(), params->download_id); |
| 798 if (download_item == NULL) { | 878 if (download_item == NULL) { |
| 799 // This could be due to an invalid download ID, or it could be due to the | 879 // This could be due to an invalid download ID, or it could be due to the |
| 800 // download not being currently active. | 880 // download not being currently active. |
| 801 error_ = download_extension_errors::kInvalidOperationError; | 881 error_ = download_extension_errors::kInvalidOperationError; |
| 802 } else { | 882 } else { |
| 803 // Note that if the item isn't paused, this will be a no-op, and | 883 // Note that if the item isn't paused, this will be a no-op, and |
| 804 // we will silently treat the extension call as a success. | 884 // the extension call will seem successful. |
| 805 download_item->Resume(); | 885 download_item->Resume(); |
| 806 } | 886 } |
| 807 if (error_.empty()) | 887 if (error_.empty()) |
| 808 RecordApiFunctions(DOWNLOADS_FUNCTION_RESUME); | 888 RecordApiFunctions(DOWNLOADS_FUNCTION_RESUME); |
| 809 return error_.empty(); | 889 return error_.empty(); |
| 810 } | 890 } |
| 811 | 891 |
| 812 DownloadsCancelFunction::DownloadsCancelFunction() {} | 892 DownloadsCancelFunction::DownloadsCancelFunction() {} |
| 893 | |
| 813 DownloadsCancelFunction::~DownloadsCancelFunction() {} | 894 DownloadsCancelFunction::~DownloadsCancelFunction() {} |
| 814 | 895 |
| 815 bool DownloadsCancelFunction::RunImpl() { | 896 bool DownloadsCancelFunction::RunImpl() { |
| 816 scoped_ptr<extensions::api::downloads::Resume::Params> params( | 897 scoped_ptr<extensions::api::downloads::Resume::Params> params( |
| 817 extensions::api::downloads::Resume::Params::Create(*args_)); | 898 extensions::api::downloads::Resume::Params::Create(*args_)); |
| 818 EXTENSION_FUNCTION_VALIDATE(params.get()); | 899 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 819 DownloadItem* download_item = GetDownloadIfInProgress( | 900 DownloadItem* download_item = GetDownloadIfInProgress( |
| 820 profile(), include_incognito(), params->download_id); | 901 profile(), include_incognito(), params->download_id); |
| 821 if (download_item != NULL) | 902 if (download_item != NULL) |
| 822 download_item->Cancel(true); | 903 download_item->Cancel(true); |
| 823 // |download_item| can be NULL if the download ID was invalid or if the | 904 // |download_item| can be NULL if the download ID was invalid or if the |
| 824 // download is not currently active. Either way, we don't consider it a | 905 // download is not currently active. Either way, it's not a failure. |
| 825 // failure. | |
| 826 RecordApiFunctions(DOWNLOADS_FUNCTION_CANCEL); | 906 RecordApiFunctions(DOWNLOADS_FUNCTION_CANCEL); |
| 827 return true; | 907 return true; |
| 828 } | 908 } |
| 829 | 909 |
| 830 DownloadsEraseFunction::DownloadsEraseFunction() {} | 910 DownloadsEraseFunction::DownloadsEraseFunction() {} |
| 911 | |
| 831 DownloadsEraseFunction::~DownloadsEraseFunction() {} | 912 DownloadsEraseFunction::~DownloadsEraseFunction() {} |
| 832 | 913 |
| 833 bool DownloadsEraseFunction::RunImpl() { | 914 bool DownloadsEraseFunction::RunImpl() { |
| 834 scoped_ptr<extensions::api::downloads::Erase::Params> params( | 915 scoped_ptr<extensions::api::downloads::Erase::Params> params( |
| 835 extensions::api::downloads::Erase::Params::Create(*args_)); | 916 extensions::api::downloads::Erase::Params::Create(*args_)); |
| 836 EXTENSION_FUNCTION_VALIDATE(params.get()); | 917 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 837 DownloadManager* manager = NULL; | 918 DownloadManager* manager = NULL; |
| 838 DownloadManager* incognito_manager = NULL; | 919 DownloadManager* incognito_manager = NULL; |
| 839 GetManagers(profile(), include_incognito(), &manager, &incognito_manager); | 920 GetManagers(profile(), include_incognito(), &manager, &incognito_manager); |
| 840 DownloadQuery::DownloadVector results; | 921 DownloadQuery::DownloadVector results; |
| 841 RunDownloadQuery(params->query, | 922 RunDownloadQuery(params->query, |
| 842 manager, | 923 manager, |
| 843 incognito_manager, | 924 incognito_manager, |
| 844 &error_, | 925 &error_, |
| 845 &results); | 926 &results); |
| 846 if (!error_.empty()) | 927 if (!error_.empty()) |
| 847 return false; | 928 return false; |
| 848 base::ListValue* json_results = new base::ListValue(); | 929 base::ListValue* json_results = new base::ListValue(); |
| 849 for (DownloadManager::DownloadVector::const_iterator it = results.begin(); | 930 for (DownloadManager::DownloadVector::const_iterator it = results.begin(); |
| 850 it != results.end(); ++it) { | 931 it != results.end(); ++it) { |
| 851 json_results->Append(base::Value::CreateIntegerValue((*it)->GetId())); | 932 json_results->Append(base::Value::CreateIntegerValue((*it)->GetId())); |
| 852 (*it)->Remove(); | 933 (*it)->Remove(); |
| 853 } | 934 } |
| 854 SetResult(json_results); | 935 SetResult(json_results); |
| 855 RecordApiFunctions(DOWNLOADS_FUNCTION_ERASE); | 936 RecordApiFunctions(DOWNLOADS_FUNCTION_ERASE); |
| 856 return true; | 937 return true; |
| 857 } | 938 } |
| 858 | 939 |
| 859 DownloadsSetDestinationFunction::DownloadsSetDestinationFunction() {} | 940 DownloadsAcceptDangerFunction::DownloadsAcceptDangerFunction() {} |
| 860 DownloadsSetDestinationFunction::~DownloadsSetDestinationFunction() {} | |
| 861 | 941 |
| 862 bool DownloadsSetDestinationFunction::RunImpl() { | |
| 863 scoped_ptr<extensions::api::downloads::SetDestination::Params> params( | |
| 864 extensions::api::downloads::SetDestination::Params::Create(*args_)); | |
| 865 EXTENSION_FUNCTION_VALIDATE(params.get()); | |
| 866 error_ = download_extension_errors::kNotImplementedError; | |
| 867 if (error_.empty()) | |
| 868 RecordApiFunctions(DOWNLOADS_FUNCTION_SET_DESTINATION); | |
| 869 return error_.empty(); | |
| 870 } | |
| 871 | |
| 872 DownloadsAcceptDangerFunction::DownloadsAcceptDangerFunction() {} | |
| 873 DownloadsAcceptDangerFunction::~DownloadsAcceptDangerFunction() {} | 942 DownloadsAcceptDangerFunction::~DownloadsAcceptDangerFunction() {} |
| 874 | 943 |
| 875 bool DownloadsAcceptDangerFunction::RunImpl() { | 944 bool DownloadsAcceptDangerFunction::RunImpl() { |
| 876 scoped_ptr<extensions::api::downloads::AcceptDanger::Params> params( | 945 scoped_ptr<extensions::api::downloads::AcceptDanger::Params> params( |
| 877 extensions::api::downloads::AcceptDanger::Params::Create(*args_)); | 946 extensions::api::downloads::AcceptDanger::Params::Create(*args_)); |
| 878 EXTENSION_FUNCTION_VALIDATE(params.get()); | 947 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 879 error_ = download_extension_errors::kNotImplementedError; | 948 error_ = download_extension_errors::kNotImplementedError; |
| 880 if (error_.empty()) | 949 if (error_.empty()) |
| 881 RecordApiFunctions(DOWNLOADS_FUNCTION_ACCEPT_DANGER); | 950 RecordApiFunctions(DOWNLOADS_FUNCTION_ACCEPT_DANGER); |
| 882 return error_.empty(); | 951 return error_.empty(); |
| 883 } | 952 } |
| 884 | 953 |
| 885 DownloadsShowFunction::DownloadsShowFunction() {} | 954 DownloadsShowFunction::DownloadsShowFunction() {} |
| 955 | |
| 886 DownloadsShowFunction::~DownloadsShowFunction() {} | 956 DownloadsShowFunction::~DownloadsShowFunction() {} |
| 887 | 957 |
| 888 bool DownloadsShowFunction::RunImpl() { | 958 bool DownloadsShowFunction::RunImpl() { |
| 889 scoped_ptr<extensions::api::downloads::Show::Params> params( | 959 scoped_ptr<extensions::api::downloads::Show::Params> params( |
| 890 extensions::api::downloads::Show::Params::Create(*args_)); | 960 extensions::api::downloads::Show::Params::Create(*args_)); |
| 891 EXTENSION_FUNCTION_VALIDATE(params.get()); | 961 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 892 DownloadItem* download_item = GetDownload( | 962 DownloadItem* download_item = GetDownload( |
| 893 profile(), include_incognito(), params->download_id); | 963 profile(), include_incognito(), params->download_id); |
| 894 if (!download_item) { | 964 if (!download_item) { |
| 895 error_ = download_extension_errors::kInvalidOperationError; | 965 error_ = download_extension_errors::kInvalidOperationError; |
| 896 return false; | 966 return false; |
| 897 } | 967 } |
| 898 download_item->ShowDownloadInShell(); | 968 download_item->ShowDownloadInShell(); |
| 899 RecordApiFunctions(DOWNLOADS_FUNCTION_SHOW); | 969 RecordApiFunctions(DOWNLOADS_FUNCTION_SHOW); |
| 900 return true; | 970 return true; |
| 901 } | 971 } |
| 902 | 972 |
| 903 DownloadsOpenFunction::DownloadsOpenFunction() {} | 973 DownloadsOpenFunction::DownloadsOpenFunction() {} |
| 974 | |
| 904 DownloadsOpenFunction::~DownloadsOpenFunction() {} | 975 DownloadsOpenFunction::~DownloadsOpenFunction() {} |
| 905 | 976 |
| 906 bool DownloadsOpenFunction::RunImpl() { | 977 bool DownloadsOpenFunction::RunImpl() { |
| 907 scoped_ptr<extensions::api::downloads::Open::Params> params( | 978 scoped_ptr<extensions::api::downloads::Open::Params> params( |
| 908 extensions::api::downloads::Open::Params::Create(*args_)); | 979 extensions::api::downloads::Open::Params::Create(*args_)); |
| 909 EXTENSION_FUNCTION_VALIDATE(params.get()); | 980 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 910 DownloadItem* download_item = GetDownload( | 981 DownloadItem* download_item = GetDownload( |
| 911 profile(), include_incognito(), params->download_id); | 982 profile(), include_incognito(), params->download_id); |
| 912 if (!download_item || !download_item->IsComplete()) { | 983 if (!download_item || !download_item->IsComplete()) { |
| 913 error_ = download_extension_errors::kInvalidOperationError; | 984 error_ = download_extension_errors::kInvalidOperationError; |
| 914 return false; | 985 return false; |
| 915 } | 986 } |
| 916 download_item->OpenDownload(); | 987 download_item->OpenDownload(); |
| 917 RecordApiFunctions(DOWNLOADS_FUNCTION_OPEN); | 988 RecordApiFunctions(DOWNLOADS_FUNCTION_OPEN); |
| 918 return true; | 989 return true; |
| 919 } | 990 } |
| 920 | 991 |
| 921 DownloadsDragFunction::DownloadsDragFunction() {} | 992 DownloadsDragFunction::DownloadsDragFunction() {} |
| 993 | |
| 922 DownloadsDragFunction::~DownloadsDragFunction() {} | 994 DownloadsDragFunction::~DownloadsDragFunction() {} |
| 923 | 995 |
| 924 bool DownloadsDragFunction::RunImpl() { | 996 bool DownloadsDragFunction::RunImpl() { |
| 925 scoped_ptr<extensions::api::downloads::Drag::Params> params( | 997 scoped_ptr<extensions::api::downloads::Drag::Params> params( |
| 926 extensions::api::downloads::Drag::Params::Create(*args_)); | 998 extensions::api::downloads::Drag::Params::Create(*args_)); |
| 927 EXTENSION_FUNCTION_VALIDATE(params.get()); | 999 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 928 DownloadItem* download_item = GetDownload( | 1000 DownloadItem* download_item = GetDownload( |
| 929 profile(), include_incognito(), params->download_id); | 1001 profile(), include_incognito(), params->download_id); |
| 930 content::WebContents* web_contents = | 1002 content::WebContents* web_contents = |
| 931 dispatcher()->delegate()->GetAssociatedWebContents(); | 1003 dispatcher()->delegate()->GetAssociatedWebContents(); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 966 int icon_size = kDefaultIconSize; | 1038 int icon_size = kDefaultIconSize; |
| 967 if (options && options->size.get()) | 1039 if (options && options->size.get()) |
| 968 icon_size = *options->size.get(); | 1040 icon_size = *options->size.get(); |
| 969 DownloadItem* download_item = GetDownload( | 1041 DownloadItem* download_item = GetDownload( |
| 970 profile(), include_incognito(), params->download_id); | 1042 profile(), include_incognito(), params->download_id); |
| 971 if (!download_item || download_item->GetTargetFilePath().empty()) { | 1043 if (!download_item || download_item->GetTargetFilePath().empty()) { |
| 972 error_ = download_extension_errors::kInvalidOperationError; | 1044 error_ = download_extension_errors::kInvalidOperationError; |
| 973 return false; | 1045 return false; |
| 974 } | 1046 } |
| 975 // In-progress downloads return the intermediate filename for GetFullPath() | 1047 // In-progress downloads return the intermediate filename for GetFullPath() |
| 976 // which doesn't have the final extension. Therefore we won't be able to | 1048 // which doesn't have the final extension. Therefore a good file icon can't be |
| 977 // derive a good file icon for it. So we use GetTargetFilePath() instead. | 1049 // found, so use GetTargetFilePath() instead. |
| 978 DCHECK(icon_extractor_.get()); | 1050 DCHECK(icon_extractor_.get()); |
| 979 DCHECK(icon_size == 16 || icon_size == 32); | 1051 DCHECK(icon_size == 16 || icon_size == 32); |
| 980 EXTENSION_FUNCTION_VALIDATE(icon_extractor_->ExtractIconURLForPath( | 1052 EXTENSION_FUNCTION_VALIDATE(icon_extractor_->ExtractIconURLForPath( |
| 981 download_item->GetTargetFilePath(), | 1053 download_item->GetTargetFilePath(), |
| 982 IconLoaderSizeFromPixelSize(icon_size), | 1054 IconLoaderSizeFromPixelSize(icon_size), |
| 983 base::Bind(&DownloadsGetFileIconFunction::OnIconURLExtracted, this))); | 1055 base::Bind(&DownloadsGetFileIconFunction::OnIconURLExtracted, this))); |
| 984 return true; | 1056 return true; |
| 985 } | 1057 } |
| 986 | 1058 |
| 987 void DownloadsGetFileIconFunction::OnIconURLExtracted(const std::string& url) { | 1059 void DownloadsGetFileIconFunction::OnIconURLExtracted(const std::string& url) { |
| 988 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1060 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 989 if (url.empty()) { | 1061 if (url.empty()) { |
| 990 error_ = download_extension_errors::kIconNotFoundError; | 1062 error_ = download_extension_errors::kIconNotFoundError; |
| 991 } else { | 1063 } else { |
| 992 RecordApiFunctions(DOWNLOADS_FUNCTION_GET_FILE_ICON); | 1064 RecordApiFunctions(DOWNLOADS_FUNCTION_GET_FILE_ICON); |
| 993 SetResult(base::Value::CreateStringValue(url)); | 1065 SetResult(base::Value::CreateStringValue(url)); |
| 994 } | 1066 } |
| 995 SendResponse(error_.empty()); | 1067 SendResponse(error_.empty()); |
| 996 } | 1068 } |
| 997 | 1069 |
| 1070 // The method by which extensions hook into the filename determination process | |
|
Randy Smith (Not in Mondays)
2013/01/14 21:02:29
nit: I'd find this comment easier to read if it ha
benjhayden
2013/01/17 02:52:05
Done.
| |
| 1071 // is based on the method by which the webRequest API allows extensions to hook | |
| 1072 // into the resource loading process. Extensions that wish to play a part in | |
| 1073 // the filename determination process call | |
| 1074 // chrome.downloads.onDeterminingFilename.addListener, which secretly (see | |
| 1075 // chrome/renderer/resources/extensions/downloads_custom_bindings.js) calls | |
| 1076 // DownloadsInternalAddFilenameDeterminerFunction (see ../downloads_internal/), | |
| 1077 // which adds the extension's ID to the profile's ExtensionDownloadsEventRouter | |
| 1078 // (EDER). When a download's filename is being determined, | |
| 1079 // ChromeDownloadManagerDelegate::CheckVisitedReferrerBeforeDone (CVRBD) passes | |
| 1080 // 2 callbacks to EDER::OnDownloadFilenameDetermined (ODFD), which stores the | |
| 1081 // callbacks in the item's ExtensionDownloadsEventRouterData (EDERD) along with | |
| 1082 // all of the extension IDs that are listening for onDeterminingFilename events. | |
| 1083 // ODFD dispatches chrome.downloads.onDeterminingFilename. When the extension's | |
| 1084 // event handler returns, downloads_custom_bindings.js calls | |
| 1085 // DownloadsInternalDetermineFilenameFunction::RunImpl, which notifies the | |
| 1086 // item's EDERD. When the last extension's event handler returns, EDERD calls | |
| 1087 // one of the two callbacks that CVRBD passed to ODFD, allowing CDMD to complete | |
| 1088 // the filename determination process. If multiple extensions wish to override | |
| 1089 // the filename, then the last one wins. However, there's no deterministic way | |
| 1090 // to determine which extension will finish last, so users are advised (in the | |
| 1091 // developer documentation in downloads.idl) to try to use extensions that won't | |
| 1092 // conflict. | |
|
Randy Smith (Not in Mondays)
2013/01/14 21:02:29
If I read the code above, it's not the last one re
benjhayden
2013/01/17 02:52:05
Changed the code and updated this comment.
| |
| 1093 | |
| 1094 bool ExtensionDownloadsEventRouter::AddFilenameDeterminer( | |
| 1095 Profile* profile, | |
| 1096 bool include_incognito, | |
| 1097 const std::string& ext_id, | |
| 1098 const std::string& sub_event_id) { | |
| 1099 if (include_incognito && profile->HasOffTheRecordProfile()) { | |
|
Randy Smith (Not in Mondays)
2013/01/14 21:02:29
My confusion, your opportunity to enlighten :-}: I
benjhayden
2013/01/17 02:52:05
PTAL, this changed.
| |
| 1100 AddFilenameDeterminer(profile->GetOffTheRecordProfile(), | |
|
Randy Smith (Not in Mondays)
2013/01/14 21:02:29
Ignoring return value? That at least should have
benjhayden
2013/01/17 02:52:05
Done.
| |
| 1101 false, | |
| 1102 ext_id, | |
| 1103 sub_event_id); | |
| 1104 } | |
| 1105 ExtensionDownloadsEventRouter* router = | |
| 1106 DownloadServiceFactory::GetForProfile(profile)->GetExtensionEventRouter(); | |
| 1107 for (DeterminerVector::const_iterator iter = router->determiners_.begin(); | |
| 1108 iter != router->determiners_.end(); ++iter) { | |
| 1109 if (iter->first == ext_id && iter->second == sub_event_id) | |
| 1110 return false; | |
|
Randy Smith (Not in Mondays)
2013/01/14 21:02:29
What is the larger implication about false returns
benjhayden
2013/01/17 02:52:05
Done.
| |
| 1111 } | |
| 1112 router->determiners_.push_back(make_pair(ext_id, sub_event_id)); | |
| 1113 return true; | |
| 1114 } | |
| 1115 | |
| 1116 bool ExtensionDownloadsEventRouter::RemoveFilenameDeterminer( | |
| 1117 Profile* profile, | |
| 1118 bool include_incognito, | |
| 1119 const std::string& ext_id, | |
| 1120 const std::string& sub_event_id) { | |
| 1121 if (include_incognito && profile->HasOffTheRecordProfile()) { | |
| 1122 RemoveFilenameDeterminer(profile->GetOffTheRecordProfile(), | |
| 1123 false, | |
| 1124 ext_id, | |
| 1125 sub_event_id); | |
| 1126 } | |
| 1127 ExtensionDownloadsEventRouter* router = | |
| 1128 DownloadServiceFactory::GetForProfile(profile)->GetExtensionEventRouter(); | |
| 1129 for (DeterminerVector::iterator iter = router->determiners_.begin(); | |
| 1130 iter != router->determiners_.end(); ++iter) { | |
| 1131 if (iter->first == ext_id && iter->second == sub_event_id) { | |
| 1132 router->determiners_.erase(iter); | |
| 1133 return true; | |
| 1134 } | |
| 1135 } | |
| 1136 return false; | |
| 1137 } | |
| 1138 | |
| 1139 bool ExtensionDownloadsEventRouter::DetermineFilename( | |
| 1140 Profile* profile, | |
| 1141 bool include_incognito, | |
| 1142 const std::string& ext_id, | |
| 1143 const std::string& sub_event_id, | |
| 1144 int download_id, | |
| 1145 const FilePath& filename, | |
| 1146 bool overwrite) { | |
| 1147 DownloadItem* item = GetDownloadIfInProgress( | |
|
Randy Smith (Not in Mondays)
2013/01/14 21:02:29
Is there any issue here with downloads resumption?
benjhayden
2013/01/17 02:52:05
I added EDERD::ClearPendingDeterminers, and call i
Randy Smith (Not in Mondays)
2013/01/17 19:15:42
I think that's ok. At least, the only problem I s
| |
| 1148 profile, include_incognito, download_id); | |
| 1149 if (!item) | |
| 1150 return false; | |
| 1151 ExtensionDownloadsEventRouterData* data = | |
| 1152 ExtensionDownloadsEventRouterData::Get(item); | |
| 1153 if (!data) | |
| 1154 return false; | |
| 1155 return data->DeterminerCallback(ext_id, sub_event_id, filename, overwrite); | |
| 1156 } | |
| 1157 | |
| 998 ExtensionDownloadsEventRouter::ExtensionDownloadsEventRouter( | 1158 ExtensionDownloadsEventRouter::ExtensionDownloadsEventRouter( |
| 999 Profile* profile, | 1159 Profile* profile, |
| 1000 DownloadManager* manager) | 1160 DownloadManager* manager) |
| 1001 : profile_(profile), | 1161 : profile_(profile), |
| 1002 ALLOW_THIS_IN_INITIALIZER_LIST(notifier_(manager, this)) { | 1162 ALLOW_THIS_IN_INITIALIZER_LIST(notifier_(manager, this)) { |
| 1003 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1163 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1004 DCHECK(profile_); | 1164 DCHECK(profile_); |
| 1165 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, | |
| 1166 content::Source<Profile>(profile_)); | |
| 1167 } | |
| 1168 | |
| 1169 void ExtensionDownloadsEventRouter::Observe( | |
| 1170 int type, | |
| 1171 const content::NotificationSource& source, | |
| 1172 const content::NotificationDetails& details) { | |
| 1173 switch (type) { | |
| 1174 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { | |
| 1175 const extensions::Extension* extension = content::Details< | |
| 1176 extensions::UnloadedExtensionInfo>(details)->extension; | |
| 1177 for (DeterminerVector::iterator iter = determiners_.begin(); | |
| 1178 iter != determiners_.end(); ++iter) { | |
| 1179 if (iter->first == extension->id()) | |
| 1180 iter = determiners_.erase(iter); | |
|
Randy Smith (Not in Mondays)
2013/01/14 21:02:29
What about download items that are waiting for res
benjhayden
2013/01/17 02:52:05
Done.
| |
| 1181 } | |
| 1182 break; | |
| 1183 } | |
| 1184 default: | |
| 1185 NOTREACHED(); | |
| 1186 break; | |
| 1187 } | |
| 1005 } | 1188 } |
| 1006 | 1189 |
| 1007 ExtensionDownloadsEventRouter::~ExtensionDownloadsEventRouter() { | 1190 ExtensionDownloadsEventRouter::~ExtensionDownloadsEventRouter() { |
| 1008 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1191 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1009 } | 1192 } |
| 1010 | 1193 |
| 1011 void ExtensionDownloadsEventRouter::OnDownloadCreated( | 1194 void ExtensionDownloadsEventRouter::OnDownloadCreated( |
| 1012 DownloadManager* manager, DownloadItem* download_item) { | 1195 DownloadManager* manager, DownloadItem* download_item) { |
| 1013 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1196 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1014 if (download_item->IsTemporary()) | 1197 if (download_item->IsTemporary()) |
| 1015 return; | 1198 return; |
| 1016 | 1199 |
| 1017 scoped_ptr<base::DictionaryValue> json_item( | 1200 scoped_ptr<base::DictionaryValue> json_item( |
| 1018 DownloadItemToJSON(download_item, profile_->IsOffTheRecord())); | 1201 DownloadItemToJSON(download_item, profile_->IsOffTheRecord())); |
| 1019 DispatchEvent(extensions::event_names::kOnDownloadCreated, | 1202 DispatchEvent(extensions::event_names::kOnDownloadCreated, |
| 1020 json_item->DeepCopy()); | 1203 json_item->DeepCopy()); |
| 1021 if (!ExtensionDownloadsEventRouterData::Get(download_item)) | 1204 if (!ExtensionDownloadsEventRouterData::Get(download_item)) |
| 1022 new ExtensionDownloadsEventRouterData(download_item, json_item.Pass()); | 1205 new ExtensionDownloadsEventRouterData(download_item, json_item.Pass()); |
| 1023 } | 1206 } |
| 1024 | 1207 |
| 1208 void ExtensionDownloadsEventRouter::OnDownloadFilenameDetermined( | |
| 1209 DownloadItem* item, | |
| 1210 const FilePath& suggested_path, | |
| 1211 const base::Closure& no_change, | |
| 1212 const FilenameChangedCallback& change) { | |
| 1213 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 1214 if (determiners_.empty()) { | |
| 1215 no_change.Run(); | |
| 1216 return; | |
| 1217 } | |
| 1218 | |
| 1219 ExtensionDownloadsEventRouterData* data = | |
| 1220 ExtensionDownloadsEventRouterData::Get(item); | |
| 1221 data->set_filename_change_callbacks(no_change, change); | |
| 1222 std::set<std::string> sub_events; | |
| 1223 for (DeterminerVector::const_iterator iter = determiners_.begin(); | |
| 1224 iter != determiners_.end(); ++iter) { | |
| 1225 data->AddPendingDeterminer(iter->first, iter->second); | |
| 1226 sub_events.insert(iter->second); | |
| 1227 } | |
| 1228 std::string event_name( | |
| 1229 extensions::event_names::kOnDownloadDeterminingFilename); | |
| 1230 event_name += "/"; | |
| 1231 for (std::set<std::string>::const_iterator iter = sub_events.begin(); | |
| 1232 iter != sub_events.end(); ++iter) { | |
| 1233 base::DictionaryValue* json = DownloadItemToJSON( | |
| 1234 item, profile_->IsOffTheRecord()).release(); | |
| 1235 json->SetString(kFilenameKey, suggested_path.LossyDisplayName()); | |
| 1236 DispatchEvent((event_name + (*iter)).c_str(), json); | |
| 1237 } | |
| 1238 } | |
| 1239 | |
| 1025 void ExtensionDownloadsEventRouter::OnDownloadUpdated( | 1240 void ExtensionDownloadsEventRouter::OnDownloadUpdated( |
| 1026 DownloadManager* manager, DownloadItem* download_item) { | 1241 DownloadManager* manager, DownloadItem* download_item) { |
| 1027 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1242 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1028 if (download_item->IsTemporary()) | 1243 if (download_item->IsTemporary()) |
| 1029 return; | 1244 return; |
| 1030 | 1245 |
| 1031 ExtensionDownloadsEventRouterData* data = | 1246 ExtensionDownloadsEventRouterData* data = |
| 1032 ExtensionDownloadsEventRouterData::Get(download_item); | 1247 ExtensionDownloadsEventRouterData::Get(download_item); |
| 1033 if (!data) { | 1248 if (!data) { |
| 1034 // The download_item probably transitioned from temporary to not temporary. | 1249 // The download_item probably transitioned from temporary to not temporary. |
| 1035 OnDownloadCreated(manager, download_item); | 1250 OnDownloadCreated(manager, download_item); |
| 1036 return; | 1251 return; |
| 1037 } | 1252 } |
| 1038 scoped_ptr<base::DictionaryValue> new_json(DownloadItemToJSON( | 1253 scoped_ptr<base::DictionaryValue> new_json(DownloadItemToJSON( |
| 1039 download_item, profile_->IsOffTheRecord())); | 1254 download_item, profile_->IsOffTheRecord())); |
| 1040 scoped_ptr<base::DictionaryValue> delta(new base::DictionaryValue()); | 1255 scoped_ptr<base::DictionaryValue> delta(new base::DictionaryValue()); |
| 1041 delta->SetInteger(kIdKey, download_item->GetId()); | 1256 delta->SetInteger(kIdKey, download_item->GetId()); |
| 1042 std::set<std::string> new_fields; | 1257 std::set<std::string> new_fields; |
| 1043 bool changed = false; | 1258 bool changed = false; |
| 1044 | 1259 |
| 1045 // For each field in the new json representation of the download_item except | 1260 // For each field in the new json representation of the download_item except |
| 1046 // the bytesReceived field, if the field has changed from the previous old | 1261 // the bytesReceived field, if the field has changed from the previous old |
| 1047 // json, set the differences in the |delta| object and remember that something | 1262 // json, set the differences in the |delta| object and remember that something |
| 1048 // significant changed. | 1263 // significant changed. |
| 1049 for (base::DictionaryValue::Iterator iter(*new_json.get()); | 1264 for (base::DictionaryValue::Iterator iter(*new_json.get()); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1094 void ExtensionDownloadsEventRouter::DispatchEvent( | 1309 void ExtensionDownloadsEventRouter::DispatchEvent( |
| 1095 const char* event_name, base::Value* arg) { | 1310 const char* event_name, base::Value* arg) { |
| 1096 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1311 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1097 scoped_ptr<base::ListValue> args(new base::ListValue()); | 1312 scoped_ptr<base::ListValue> args(new base::ListValue()); |
| 1098 args->Append(arg); | 1313 args->Append(arg); |
| 1099 std::string json_args; | 1314 std::string json_args; |
| 1100 base::JSONWriter::Write(args.get(), &json_args); | 1315 base::JSONWriter::Write(args.get(), &json_args); |
| 1101 // There is a one EDER for each on-record Profile, and a separate EDER for | 1316 // There is a one EDER for each on-record Profile, and a separate EDER for |
| 1102 // each off-record Profile, so there is exactly one EDER for each | 1317 // each off-record Profile, so there is exactly one EDER for each |
| 1103 // DownloadManager. EDER only watches its own DM, so all the items that an | 1318 // DownloadManager. EDER only watches its own DM, so all the items that an |
| 1104 // EDER sees are either all on-record or all off-record. However, we want | 1319 // EDER sees are either all on-record or all off-record. However, extensions |
| 1105 // extensions in off-record contexts to see on-record items. So, if this EDER | 1320 // in off-record contexts should see on-record items. So, if this EDER is |
| 1106 // is watching an on-record DM, and there is a corresponding off-record | 1321 // watching an on-record DM, and there is a corresponding off-record Profile, |
| 1107 // Profile, then dispatch this event to both the on-record Profile and the | 1322 // then dispatch this event to both the on-record Profile and the off-record |
| 1108 // off-record Profile. There may or may not be an off-record Profile, so send | 1323 // Profile. There may or may not be an off-record Profile, so send a *copy* |
| 1109 // a *copy* of |args| to the off-record Profile, and Pass() |args| | 1324 // of |args| to the off-record Profile, and Pass() |args| to the Profile that |
| 1110 // to the Profile that we know is there. | 1325 // is certainly there. |
| 1111 if (profile_->HasOffTheRecordProfile() && | 1326 if (profile_->HasOffTheRecordProfile() && |
| 1112 !profile_->IsOffTheRecord()) { | 1327 !profile_->IsOffTheRecord()) { |
| 1113 DispatchEventInternal( | 1328 DispatchEventInternal( |
| 1114 profile_->GetOffTheRecordProfile(), | 1329 profile_->GetOffTheRecordProfile(), |
| 1115 event_name, | 1330 event_name, |
| 1116 json_args, | 1331 json_args, |
| 1117 scoped_ptr<base::ListValue>(args->DeepCopy())); | 1332 scoped_ptr<base::ListValue>(args->DeepCopy())); |
| 1118 } | 1333 } |
| 1119 DispatchEventInternal(profile_, event_name, json_args, args.Pass()); | 1334 DispatchEventInternal(profile_, event_name, json_args, args.Pass()); |
| 1120 } | 1335 } |
| OLD | NEW |