diff options
author | benjhayden@chromium.org <benjhayden@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-14 19:31:44 +0000 |
---|---|---|
committer | benjhayden@chromium.org <benjhayden@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-14 19:31:44 +0000 |
commit | 370e950844015d8a97786de2a271df85653c0da8 (patch) | |
tree | 089c3c7f44f2c6ced0d9ab00217f662cfd6b2e1e /chrome | |
parent | 3907848d9a7febf2ce8ce1c9e8113947387f7556 (diff) | |
download | chromium_src-370e950844015d8a97786de2a271df85653c0da8.zip chromium_src-370e950844015d8a97786de2a271df85653c0da8.tar.gz chromium_src-370e950844015d8a97786de2a271df85653c0da8.tar.bz2 |
chrome.experimental.downloads.onCreated, onErased
Manually tested. No apitest yet because that's in 7647028. If this CL goes in before that one, then I'll add tests for these events in that CL, otherwise in this CL at that time.
Who owns what:
Randy: DownloadItem
Mihai: chrome/browser/extensions/...
Randy, Asanka, I also appreciate having your eyes on extensions/... if you have the time to make sure that I'm using the downloads/ interfaces correctly and matching the doc.
Review URL: http://codereview.chromium.org/7645029
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@101121 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
8 files changed, 207 insertions, 1 deletions
diff --git a/chrome/browser/extensions/extension_downloads_api.cc b/chrome/browser/extensions/extension_downloads_api.cc index a8f1c73..20c3125 100644 --- a/chrome/browser/extensions/extension_downloads_api.cc +++ b/chrome/browser/extensions/extension_downloads_api.cc @@ -5,9 +5,11 @@ #include "chrome/browser/extensions/extension_downloads_api.h" #include <algorithm> +#include <iterator> +#include <set> #include <string> -#include "base/bind.h" +#include "base/json/json_writer.h" #include "base/logging.h" #include "base/metrics/histogram.h" #include "base/stl_util.h" @@ -15,6 +17,8 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/download/download_util.h" #include "chrome/browser/extensions/extension_downloads_api_constants.h" +#include "chrome/browser/extensions/extension_event_names.h" +#include "chrome/browser/extensions/extension_event_router.h" #include "chrome/browser/icon_loader.h" #include "chrome/browser/icon_manager.h" #include "chrome/browser/renderer_host/chrome_render_message_filter.h" @@ -277,3 +281,106 @@ bool DownloadsDragFunction::ParseArgs() { void DownloadsDragFunction::RunInternal() { NOTIMPLEMENTED(); } + +namespace { +base::DictionaryValue* DownloadItemToJSON(DownloadItem* item) { + base::DictionaryValue* json = new base::DictionaryValue(); + json->SetInteger(constants::kIdKey, item->id()); + json->SetString(constants::kUrlKey, item->original_url().spec()); + json->SetString(constants::kFilenameKey, + item->full_path().LossyDisplayName()); + json->SetString(constants::kDangerKey, + constants::DangerString(item->GetDangerType())); + json->SetBoolean(constants::kDangerAcceptedKey, + item->safety_state() == DownloadItem::DANGEROUS_BUT_VALIDATED); + json->SetString(constants::kStateKey, + constants::StateString(item->state())); + json->SetBoolean(constants::kPausedKey, item->is_paused()); + json->SetString(constants::kMimeKey, item->mime_type()); + json->SetInteger(constants::kStartTimeKey, + (item->start_time() - base::Time::UnixEpoch()).InMilliseconds()); + json->SetInteger(constants::kBytesReceivedKey, item->received_bytes()); + json->SetInteger(constants::kTotalBytesKey, item->total_bytes()); + if (item->state() == DownloadItem::INTERRUPTED) + json->SetInteger(constants::kErrorKey, + static_cast<int>(item->last_error())); + // TODO(benjhayden): Implement endTime and fileSize. + // json->SetInteger(constants::kEndTimeKey, -1); + json->SetInteger(constants::kFileSizeKey, item->total_bytes()); + return json; +} +} // anonymous namespace + +ExtensionDownloadsEventRouter::ExtensionDownloadsEventRouter( + Profile* profile) + : profile_(profile), + manager_(profile ? profile->GetDownloadManager() : NULL) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DCHECK(profile_); + DCHECK(manager_); + manager_->AddObserver(this); +} + +ExtensionDownloadsEventRouter::~ExtensionDownloadsEventRouter() { + if (manager_) manager_->RemoveObserver(this); +} + +void ExtensionDownloadsEventRouter::ModelChanged() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DCHECK(manager_); + DownloadManager::DownloadVector current_vec; + manager_->SearchDownloads(string16(), ¤t_vec); + DownloadIdSet current_set; + ItemMap current_map; + for (DownloadManager::DownloadVector::const_iterator iter = + current_vec.begin(); + iter != current_vec.end(); ++iter) { + DownloadItem* item = *iter; + int item_id = item->id(); + // TODO(benjhayden): Remove the following line when every item's id >= 0, + // which will allow firing onErased events for items from the history. + if (item_id < 0) continue; + DCHECK(current_map.find(item_id) == current_map.end()); + current_set.insert(item_id); + current_map[item_id] = item; + } + DownloadIdSet new_set; // current_set - downloads_; + DownloadIdSet erased_set; // downloads_ - current_set; + std::insert_iterator<DownloadIdSet> new_insertor(new_set, new_set.begin()); + std::insert_iterator<DownloadIdSet> erased_insertor( + erased_set, erased_set.begin()); + std::set_difference(current_set.begin(), current_set.end(), + downloads_.begin(), downloads_.end(), + new_insertor); + std::set_difference(downloads_.begin(), downloads_.end(), + current_set.begin(), current_set.end(), + erased_insertor); + for (DownloadIdSet::const_iterator iter = new_set.begin(); + iter != new_set.end(); ++iter) { + DispatchEvent(extension_event_names::kOnDownloadCreated, + DownloadItemToJSON(current_map[*iter])); + } + for (DownloadIdSet::const_iterator iter = erased_set.begin(); + iter != erased_set.end(); ++iter) { + DispatchEvent(extension_event_names::kOnDownloadErased, + base::Value::CreateIntegerValue(*iter)); + } + downloads_.swap(current_set); +} + +void ExtensionDownloadsEventRouter::ManagerGoingDown() { + manager_ = NULL; +} + +void ExtensionDownloadsEventRouter::DispatchEvent( + const char* event_name, base::Value* arg) { + ListValue args; + args.Append(arg); + std::string json_args; + base::JSONWriter::Write(&args, false, &json_args); + profile_->GetExtensionEventRouter()->DispatchEventToRenderers( + event_name, + json_args, + profile_, + GURL()); +} diff --git a/chrome/browser/extensions/extension_downloads_api.h b/chrome/browser/extensions/extension_downloads_api.h index bd26a42..f84de39 100644 --- a/chrome/browser/extensions/extension_downloads_api.h +++ b/chrome/browser/extensions/extension_downloads_api.h @@ -242,4 +242,24 @@ class DownloadsDragFunction : public AsyncDownloadsFunction { private: DISALLOW_COPY_AND_ASSIGN(DownloadsDragFunction); }; + +class ExtensionDownloadsEventRouter : public DownloadManager::Observer { + public: + explicit ExtensionDownloadsEventRouter(Profile* profile); + virtual ~ExtensionDownloadsEventRouter(); + + virtual void ModelChanged() OVERRIDE; + virtual void ManagerGoingDown() OVERRIDE; + + private: + void DispatchEvent(const char* event_name, base::Value* json_arg); + typedef base::hash_map<int, DownloadItem*> ItemMap; + typedef std::set<int> DownloadIdSet; + + Profile* profile_; + DownloadManager* manager_; + DownloadIdSet downloads_; + + DISALLOW_COPY_AND_ASSIGN(ExtensionDownloadsEventRouter); +}; #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_DOWNLOADS_API_H_ diff --git a/chrome/browser/extensions/extension_downloads_api_constants.cc b/chrome/browser/extensions/extension_downloads_api_constants.cc index 2836fee..49943dc 100644 --- a/chrome/browser/extensions/extension_downloads_api_constants.cc +++ b/chrome/browser/extensions/extension_downloads_api_constants.cc @@ -14,5 +14,46 @@ const char kSaveAsKey[] = "saveAs"; const char kMethodKey[] = "method"; const char kHeadersKey[] = "headers"; const char kBodyKey[] = "body"; +const char kDangerSafe[] = "safe"; +const char kDangerFile[] = "file"; +const char kDangerUrl[] = "url"; +const char kStateInProgress[] = "in_progress"; +const char kStateComplete[] = "complete"; +const char kStateInterrupted[] = "interrupted"; +const char kIdKey[] = "id"; +const char kDangerKey[] = "danger"; +const char kDangerAcceptedKey[] = "dangerAccepted"; +const char kStateKey[] = "state"; +const char kPausedKey[] = "paused"; +const char kMimeKey[] = "mime"; +const char kStartTimeKey[] = "startTime"; +const char kEndTimeKey[] = "endTime"; +const char kBytesReceivedKey[] = "bytesReceived"; +const char kTotalBytesKey[] = "totalBytes"; +const char kFileSizeKey[] = "fileSize"; +const char kErrorKey[] = "error"; +const char* DangerString(DownloadItem::DangerType danger) { + switch (danger) { + case DownloadItem::NOT_DANGEROUS: return kDangerSafe; + case DownloadItem::DANGEROUS_FILE: return kDangerFile; + case DownloadItem::DANGEROUS_URL: return kDangerUrl; + default: + NOTREACHED(); + return ""; + } +} + +const char* StateString(DownloadItem::DownloadState state) { + switch (state) { + case DownloadItem::IN_PROGRESS: return kStateInProgress; + case DownloadItem::COMPLETE: return kStateComplete; + case DownloadItem::INTERRUPTED: // fall through + case DownloadItem::CANCELLED: return kStateInterrupted; + case DownloadItem::REMOVING: // fall through + default: + NOTREACHED(); + return ""; + } +} } // namespace extension_downloads_api_constants diff --git a/chrome/browser/extensions/extension_downloads_api_constants.h b/chrome/browser/extensions/extension_downloads_api_constants.h index a676060..c3c2b94 100644 --- a/chrome/browser/extensions/extension_downloads_api_constants.h +++ b/chrome/browser/extensions/extension_downloads_api_constants.h @@ -6,6 +6,8 @@ #define CHROME_BROWSER_EXTENSIONS_EXTENSION_DOWNLOADS_API_CONSTANTS_H_ #pragma once +#include "content/browser/download/download_item.h" + namespace extension_downloads_api_constants { extern const char kNotImplemented[]; @@ -16,6 +18,28 @@ extern const char kSaveAsKey[]; extern const char kMethodKey[]; extern const char kHeadersKey[]; extern const char kBodyKey[]; +extern const char kDangerSafe[]; +extern const char kDangerFile[]; +extern const char kDangerUrl[]; +extern const char kStateInProgress[]; +extern const char kStateComplete[]; +extern const char kStateInterrupted[]; +extern const char kIdKey[]; +extern const char kDangerKey[]; +extern const char kDangerAcceptedKey[]; +extern const char kStateKey[]; +extern const char kPausedKey[]; +extern const char kMimeKey[]; +extern const char kStartTimeKey[]; +extern const char kEndTimeKey[]; +extern const char kBytesReceivedKey[]; +extern const char kTotalBytesKey[]; +extern const char kFileSizeKey[]; +extern const char kErrorKey[]; + +const char* DangerString(DownloadItem::DangerType danger); + +const char* StateString(DownloadItem::DownloadState state); } // namespace extension_downloads_api_constants diff --git a/chrome/browser/extensions/extension_event_names.cc b/chrome/browser/extensions/extension_event_names.cc index fc226f3..76904bf 100644 --- a/chrome/browser/extensions/extension_event_names.cc +++ b/chrome/browser/extensions/extension_event_names.cc @@ -29,4 +29,8 @@ const char kOnFileBrowserMountCompleted[] = "fileBrowserPrivate.onMountCompleted"; const char kOnInputMethodChanged[] = "inputMethodPrivate.onChanged"; + +const char kOnDownloadCreated[] = "experimental.downloads.onCreated"; +const char kOnDownloadChanged[] = "experimental.downloads.onChanged"; +const char kOnDownloadErased[] = "experimental.downloads.onErased"; } // namespace extension_event_names diff --git a/chrome/browser/extensions/extension_event_names.h b/chrome/browser/extensions/extension_event_names.h index 0b26e4f..2e44797 100644 --- a/chrome/browser/extensions/extension_event_names.h +++ b/chrome/browser/extensions/extension_event_names.h @@ -38,6 +38,11 @@ extern const char kOnFileBrowserMountCompleted[]; // InputMethod. extern const char kOnInputMethodChanged[]; +// Downloads. +extern const char kOnDownloadCreated[]; +extern const char kOnDownloadChanged[]; +extern const char kOnDownloadErased[]; + }; // namespace extension_event_names #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_EVENT_NAMES_H_ diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc index 2cd6d79..60a864f 100644 --- a/chrome/browser/extensions/extension_service.cc +++ b/chrome/browser/extensions/extension_service.cc @@ -32,6 +32,7 @@ #include "chrome/browser/extensions/extension_browser_event_router.h" #include "chrome/browser/extensions/extension_cookies_api.h" #include "chrome/browser/extensions/extension_data_deleter.h" +#include "chrome/browser/extensions/extension_downloads_api.h" #include "chrome/browser/extensions/extension_error_reporter.h" #include "chrome/browser/extensions/extension_history_api.h" #include "chrome/browser/extensions/extension_host.h" @@ -700,6 +701,7 @@ void ExtensionService::InitEventRouters() { if (event_routers_initialized_) return; + downloads_event_router_.reset(new ExtensionDownloadsEventRouter(profile_)); history_event_router_.reset(new ExtensionHistoryEventRouter()); history_event_router_->ObserveProfile(profile_); ExtensionAccessibilityEventRouter::GetInstance()->ObserveProfile(profile_); diff --git a/chrome/browser/extensions/extension_service.h b/chrome/browser/extensions/extension_service.h index 5e791ba..51e2d91 100644 --- a/chrome/browser/extensions/extension_service.h +++ b/chrome/browser/extensions/extension_service.h @@ -49,6 +49,7 @@ class ExtensionBookmarkEventRouter; class ExtensionBrowserEventRouter; class ExtensionContentSettingsStore; class ExtensionCookiesEventRouter; +class ExtensionDownloadsEventRouter; class ExtensionFileBrowserEventRouter; class ExtensionHistoryEventRouter; class ExtensionInstallUI; @@ -763,6 +764,8 @@ class ExtensionService // Flag to make sure event routers are only initialized once. bool event_routers_initialized_; + scoped_ptr<ExtensionDownloadsEventRouter> downloads_event_router_; + scoped_ptr<ExtensionHistoryEventRouter> history_event_router_; scoped_ptr<ExtensionBrowserEventRouter> browser_event_router_; |