| 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> |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 }; | 132 }; |
| 133 COMPILE_ASSERT(arraysize(kDangerStrings) == content::DOWNLOAD_DANGER_TYPE_MAX, | 133 COMPILE_ASSERT(arraysize(kDangerStrings) == content::DOWNLOAD_DANGER_TYPE_MAX, |
| 134 download_danger_type_enum_changed); | 134 download_danger_type_enum_changed); |
| 135 | 135 |
| 136 // Note: Any change to the state strings, should be accompanied by a | 136 // Note: Any change to the state strings, should be accompanied by a |
| 137 // corresponding change to downloads.json. | 137 // corresponding change to downloads.json. |
| 138 const char* kStateStrings[] = { | 138 const char* kStateStrings[] = { |
| 139 kStateInProgress, | 139 kStateInProgress, |
| 140 kStateComplete, | 140 kStateComplete, |
| 141 kStateInterrupted, | 141 kStateInterrupted, |
| 142 NULL, | |
| 143 kStateInterrupted, | 142 kStateInterrupted, |
| 144 }; | 143 }; |
| 145 COMPILE_ASSERT(arraysize(kStateStrings) == DownloadItem::MAX_DOWNLOAD_STATE, | 144 COMPILE_ASSERT(arraysize(kStateStrings) == DownloadItem::MAX_DOWNLOAD_STATE, |
| 146 download_item_state_enum_changed); | 145 download_item_state_enum_changed); |
| 147 | 146 |
| 148 const char* DangerString(content::DownloadDangerType danger) { | 147 const char* DangerString(content::DownloadDangerType danger) { |
| 149 DCHECK(danger >= 0); | 148 DCHECK(danger >= 0); |
| 150 DCHECK(danger < static_cast<content::DownloadDangerType>( | 149 DCHECK(danger < static_cast<content::DownloadDangerType>( |
| 151 arraysize(kDangerStrings))); | 150 arraysize(kDangerStrings))); |
| 152 return kDangerStrings[danger]; | 151 return kDangerStrings[danger]; |
| 153 } | 152 } |
| 154 | 153 |
| 155 content::DownloadDangerType DangerEnumFromString(const std::string& danger) { | 154 content::DownloadDangerType DangerEnumFromString(const std::string& danger) { |
| 156 for (size_t i = 0; i < arraysize(kDangerStrings); ++i) { | 155 for (size_t i = 0; i < arraysize(kDangerStrings); ++i) { |
| 157 if (danger == kDangerStrings[i]) | 156 if (danger == kDangerStrings[i]) |
| 158 return static_cast<content::DownloadDangerType>(i); | 157 return static_cast<content::DownloadDangerType>(i); |
| 159 } | 158 } |
| 160 return content::DOWNLOAD_DANGER_TYPE_MAX; | 159 return content::DOWNLOAD_DANGER_TYPE_MAX; |
| 161 } | 160 } |
| 162 | 161 |
| 163 const char* StateString(DownloadItem::DownloadState state) { | 162 const char* StateString(DownloadItem::DownloadState state) { |
| 164 DCHECK(state >= 0); | 163 DCHECK(state >= 0); |
| 165 DCHECK(state < static_cast<DownloadItem::DownloadState>( | 164 DCHECK(state < static_cast<DownloadItem::DownloadState>( |
| 166 arraysize(kStateStrings))); | 165 arraysize(kStateStrings))); |
| 167 DCHECK(state != DownloadItem::REMOVING); | |
| 168 return kStateStrings[state]; | 166 return kStateStrings[state]; |
| 169 } | 167 } |
| 170 | 168 |
| 171 DownloadItem::DownloadState StateEnumFromString(const std::string& state) { | 169 DownloadItem::DownloadState StateEnumFromString(const std::string& state) { |
| 172 for (size_t i = 0; i < arraysize(kStateStrings); ++i) { | 170 for (size_t i = 0; i < arraysize(kStateStrings); ++i) { |
| 173 if ((kStateStrings[i] != NULL) && (state == kStateStrings[i])) | 171 if ((kStateStrings[i] != NULL) && (state == kStateStrings[i])) |
| 174 return static_cast<DownloadItem::DownloadState>(i); | 172 return static_cast<DownloadItem::DownloadState>(i); |
| 175 } | 173 } |
| 176 return DownloadItem::MAX_DOWNLOAD_STATE; | 174 return DownloadItem::MAX_DOWNLOAD_STATE; |
| 177 } | 175 } |
| (...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 813 ExtensionDownloadsEventRouter::OnChangedStat::OnChangedStat() | 811 ExtensionDownloadsEventRouter::OnChangedStat::OnChangedStat() |
| 814 : fires(0), | 812 : fires(0), |
| 815 total(0) { | 813 total(0) { |
| 816 } | 814 } |
| 817 | 815 |
| 818 ExtensionDownloadsEventRouter::OnChangedStat::~OnChangedStat() { | 816 ExtensionDownloadsEventRouter::OnChangedStat::~OnChangedStat() { |
| 819 if (total > 0) | 817 if (total > 0) |
| 820 UMA_HISTOGRAM_PERCENTAGE("Download.OnChanged", (fires * 100 / total)); | 818 UMA_HISTOGRAM_PERCENTAGE("Download.OnChanged", (fires * 100 / total)); |
| 821 } | 819 } |
| 822 | 820 |
| 821 void ExtensionDownloadsEventRouter::OnDownloadDestroyed(DownloadItem* item) { |
| 822 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 823 int download_id = item->GetId(); |
| 824 downloads_.erase(download_id); |
| 825 item->RemoveObserver(this); |
| 826 delete item_jsons_[download_id]; |
| 827 item_jsons_.erase(download_id); |
| 828 delete on_changed_stats_[download_id]; |
| 829 on_changed_stats_.erase(download_id); |
| 830 } |
| 831 |
| 832 void ExtensionDownloadsEventRouter::OnDownloadRemoved(DownloadItem* item) { |
| 833 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 834 if (!profile_) |
| 835 return; |
| 836 int download_id = item->GetId(); |
| 837 DispatchEvent(extensions::event_names::kOnDownloadErased, |
| 838 base::Value::CreateIntegerValue(download_id)); |
| 839 } |
| 840 |
| 823 void ExtensionDownloadsEventRouter::OnDownloadUpdated(DownloadItem* item) { | 841 void ExtensionDownloadsEventRouter::OnDownloadUpdated(DownloadItem* item) { |
| 824 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 842 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 843 if (!profile_) |
| 844 return; |
| 825 int download_id = item->GetId(); | 845 int download_id = item->GetId(); |
| 826 if (item->GetState() == DownloadItem::REMOVING) { | |
| 827 // The REMOVING state indicates that this item is being erased. | |
| 828 // Let's unregister as an observer so that we don't see any more updates | |
| 829 // from it, dispatch the onErased event, and remove its json and is | |
| 830 // OnChangedStat from our maps. | |
| 831 downloads_.erase(download_id); | |
| 832 item->RemoveObserver(this); | |
| 833 DispatchEvent(extensions::event_names::kOnDownloadErased, | |
| 834 base::Value::CreateIntegerValue(download_id)); | |
| 835 delete item_jsons_[download_id]; | |
| 836 item_jsons_.erase(download_id); | |
| 837 delete on_changed_stats_[download_id]; | |
| 838 on_changed_stats_.erase(download_id); | |
| 839 return; | |
| 840 } | |
| 841 | 846 |
| 842 base::DictionaryValue* old_json = item_jsons_[download_id]; | 847 base::DictionaryValue* old_json = item_jsons_[download_id]; |
| 843 scoped_ptr<base::DictionaryValue> new_json(DownloadItemToJSON(item)); | 848 scoped_ptr<base::DictionaryValue> new_json(DownloadItemToJSON(item)); |
| 844 scoped_ptr<base::DictionaryValue> delta(new base::DictionaryValue()); | 849 scoped_ptr<base::DictionaryValue> delta(new base::DictionaryValue()); |
| 845 delta->SetInteger(kIdKey, download_id); | 850 delta->SetInteger(kIdKey, download_id); |
| 846 std::set<std::string> new_fields; | 851 std::set<std::string> new_fields; |
| 847 bool changed = false; | 852 bool changed = false; |
| 848 | 853 |
| 849 // For each field in the new json representation of the item except the | 854 // For each field in the new json representation of the item except the |
| 850 // bytesReceived field, if the field has changed from the previous old json, | 855 // bytesReceived field, if the field has changed from the previous old json, |
| (...skipping 28 matching lines...) Expand all Loading... |
| 879 // Update the OnChangedStat and dispatch the event if something significant | 884 // Update the OnChangedStat and dispatch the event if something significant |
| 880 // changed. Replace the stored json with the new json. | 885 // changed. Replace the stored json with the new json. |
| 881 ++(on_changed_stats_[download_id]->total); | 886 ++(on_changed_stats_[download_id]->total); |
| 882 if (changed) { | 887 if (changed) { |
| 883 DispatchEvent(extensions::event_names::kOnDownloadChanged, delta.release()); | 888 DispatchEvent(extensions::event_names::kOnDownloadChanged, delta.release()); |
| 884 ++(on_changed_stats_[download_id]->fires); | 889 ++(on_changed_stats_[download_id]->fires); |
| 885 } | 890 } |
| 886 item_jsons_[download_id]->Swap(new_json.get()); | 891 item_jsons_[download_id]->Swap(new_json.get()); |
| 887 } | 892 } |
| 888 | 893 |
| 889 void ExtensionDownloadsEventRouter::OnDownloadOpened(DownloadItem* item) { | |
| 890 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 891 } | |
| 892 | |
| 893 void ExtensionDownloadsEventRouter::ModelChanged(DownloadManager* manager) { | 894 void ExtensionDownloadsEventRouter::ModelChanged(DownloadManager* manager) { |
| 894 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 895 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 895 DCHECK(manager_ == manager); | 896 DCHECK(manager_ == manager); |
| 896 typedef std::set<int> DownloadIdSet; | 897 typedef std::set<int> DownloadIdSet; |
| 897 | 898 |
| 898 // Get all the download items. | 899 // Get all the download items. |
| 899 DownloadManager::DownloadVector current_vec; | 900 DownloadManager::DownloadVector current_vec; |
| 900 manager_->SearchDownloads(string16(), ¤t_vec); | 901 manager_->SearchDownloads(string16(), ¤t_vec); |
| 901 | 902 |
| 902 // Populate set<>s of download item identifiers so that we can find | 903 // Populate set<>s of download item identifiers so that we can find |
| (...skipping 29 matching lines...) Expand all Loading... |
| 932 scoped_ptr<base::DictionaryValue> item( | 933 scoped_ptr<base::DictionaryValue> item( |
| 933 DownloadItemToJSON(current_map[*iter])); | 934 DownloadItemToJSON(current_map[*iter])); |
| 934 DispatchEvent(extensions::event_names::kOnDownloadCreated, | 935 DispatchEvent(extensions::event_names::kOnDownloadCreated, |
| 935 item->DeepCopy()); | 936 item->DeepCopy()); |
| 936 DCHECK(item_jsons_.find(*iter) == item_jsons_.end()); | 937 DCHECK(item_jsons_.find(*iter) == item_jsons_.end()); |
| 937 on_changed_stats_[*iter] = new OnChangedStat(); | 938 on_changed_stats_[*iter] = new OnChangedStat(); |
| 938 current_map[*iter]->AddObserver(this); | 939 current_map[*iter]->AddObserver(this); |
| 939 item_jsons_[*iter] = item.release(); | 940 item_jsons_[*iter] = item.release(); |
| 940 } | 941 } |
| 941 downloads_.swap(current_map); | 942 downloads_.swap(current_map); |
| 942 | |
| 943 // Dispatching onErased is handled in OnDownloadUpdated when an item | |
| 944 // transitions to the REMOVING state. | |
| 945 } | 943 } |
| 946 | 944 |
| 947 void ExtensionDownloadsEventRouter::ManagerGoingDown( | 945 void ExtensionDownloadsEventRouter::ManagerGoingDown( |
| 948 DownloadManager* manager) { | 946 DownloadManager* manager) { |
| 949 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 947 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 950 manager_->RemoveObserver(this); | 948 manager_->RemoveObserver(this); |
| 951 manager_ = NULL; | 949 manager_ = NULL; |
| 950 profile_ = NULL; |
| 952 } | 951 } |
| 953 | 952 |
| 954 void ExtensionDownloadsEventRouter::DispatchEvent( | 953 void ExtensionDownloadsEventRouter::DispatchEvent( |
| 955 const char* event_name, base::Value* arg) { | 954 const char* event_name, base::Value* arg) { |
| 956 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 955 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 957 base::ListValue args; | 956 base::ListValue args; |
| 958 args.Append(arg); | 957 args.Append(arg); |
| 959 std::string json_args; | 958 std::string json_args; |
| 960 base::JSONWriter::Write(&args, &json_args); | 959 base::JSONWriter::Write(&args, &json_args); |
| 961 profile_->GetExtensionEventRouter()->DispatchEventToRenderers( | 960 profile_->GetExtensionEventRouter()->DispatchEventToRenderers( |
| 962 event_name, | 961 event_name, |
| 963 json_args, | 962 json_args, |
| 964 profile_, | 963 profile_, |
| 965 GURL(), | 964 GURL(), |
| 966 extensions::EventFilteringInfo()); | 965 extensions::EventFilteringInfo()); |
| 967 | 966 |
| 968 DownloadsNotificationSource notification_source; | 967 DownloadsNotificationSource notification_source; |
| 969 notification_source.event_name = event_name; | 968 notification_source.event_name = event_name; |
| 970 notification_source.profile = profile_; | 969 notification_source.profile = profile_; |
| 971 content::NotificationService::current()->Notify( | 970 content::NotificationService::current()->Notify( |
| 972 chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT, | 971 chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT, |
| 973 content::Source<DownloadsNotificationSource>(¬ification_source), | 972 content::Source<DownloadsNotificationSource>(¬ification_source), |
| 974 content::Details<std::string>(&json_args)); | 973 content::Details<std::string>(&json_args)); |
| 975 } | 974 } |
| OLD | NEW |