Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7163)

Unified Diff: chrome/browser/extensions/extension_downloads.cc

Issue 7192016: chrome.experimental.downloads (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: merged db_handle, id; onCreated, onErased Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/extensions/extension_downloads.h ('k') | chrome/browser/extensions/extension_event_names.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/extensions/extension_downloads.cc
diff --git a/chrome/browser/extensions/extension_downloads.cc b/chrome/browser/extensions/extension_downloads.cc
new file mode 100644
index 0000000000000000000000000000000000000000..17730a737b67a42ee8060c6a7b27b00b750229f6
--- /dev/null
+++ b/chrome/browser/extensions/extension_downloads.cc
@@ -0,0 +1,415 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/extensions/extension_downloads.h"
+
+#include <algorithm>
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/stl_util-inl.h"
+#include "base/values.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/download/download_create_info.h"
+#include "chrome/browser/extensions/extension_event_router.h"
+#include "chrome/browser/download/download_file_manager.h"
+#include "chrome/browser/download/download_item.h"
+#include "chrome/browser/download/download_manager.h"
+#include "chrome/browser/download/download_query.h"
+#include "chrome/browser/download/download_util.h"
+#include "chrome/browser/icon_loader.h"
+#include "chrome/browser/icon_manager.h"
+#include "chrome/browser/renderer_host/chrome_render_message_filter.h"
+#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
+#include "content/browser/renderer_host/render_view_host.h"
+#include "content/browser/renderer_host/resource_dispatcher_host.h"
+
+bool DownloadsDownloadFunction::RunImpl() {
+ EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &options_));
+ EXTENSION_FUNCTION_VALIDATE(options_->GetString("url", &url_));
+ if (url_.empty()) {
+ error_ = "'url' cannot be empty.";
+ return false;
+ }
+ rdh_ = g_browser_process->resource_dispatcher_host();
+ if (rdh_ == NULL) {
+ error_ = "I'm afraid I can't do that.";
+ return false;
+ }
+ VLOG(1) << __FUNCTION__ << " " << url_;
+ products_ = new DictionaryValue();
+ result_.reset(products_);
+ options_->GetString("filename", &filename_);
+ options_->GetBoolean("save_as", &save_as_);
+ options_->GetString("method", &method_);
+ options_->GetDictionary("headers", &extra_headers_);
+ options_->GetString("body", &post_body_);
+ // TODO sanity check method_, extra_headers_, filename_
+ dl_man_ = profile()->GetDownloadManager();
+ tab_contents_ = BrowserList::GetLastActive()->GetSelectedTabContentsWrapper()
+ ->tab_contents();
+ resource_context_ = &profile()->GetResourceContext();
+ render_process_host_id_ = tab_contents_->GetRenderProcessHost()->id();
+ render_view_host_routing_id_ = tab_contents_->render_view_host()
+ ->routing_id();
+ VLOG(1) << __FUNCTION__ << " " << url_;
+ if (!BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, NewRunnableMethod(
+ this, &DownloadsDownloadFunction::BeginDownloadOnIOThread))) {
+ error_ = "I'm afraid I can't do that.";
+ return false;
+ }
+ return true;
+}
+
+void DownloadsDownloadFunction::BeginDownloadOnIOThread() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DVLOG(1) << __FUNCTION__ << " " << url_;
+ DownloadSaveInfo save_info;
+ save_info.file_path = FilePath(filename_);
+ net::URLRequest* request = new net::URLRequest(GURL(url_), rdh_);
+ if (method_.empty()) {
+ method_ = "GET";
+ }
+ request->set_method(method_);
+ if (extra_headers_ != NULL) {
+ DictionaryValue::key_iterator headers_end = extra_headers_->end_keys();
+ for (DictionaryValue::key_iterator headers_iter =
+ extra_headers_->begin_keys();
+ headers_iter != headers_end; ++headers_iter) {
+ std::string value;
+ if (extra_headers_->GetStringWithoutPathExpansion(
+ *headers_iter, &value)) {
+ request->SetExtraRequestHeaderByName(
+ *headers_iter, value, false/*overwrite*/);
+ }
+ }
+ }
+ if (!post_body_.empty()) {
+ request->AppendBytesToUpload(post_body_.data(), post_body_.size());
+ }
+ rdh_->BeginDownload(
+ request,
+ save_info,
+ save_as_,
+ base::Bind(&DownloadsDownloadFunction::OnStarted, this),
+ render_process_host_id_,
+ render_view_host_routing_id_,
+ *resource_context_);
+}
+
+void DownloadsDownloadFunction::OnStarted(int dl_id, int error) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ VLOG(1) << __FUNCTION__ << " " << url_ << " " << dl_id << " " << error;
+ dl_id_ = dl_id;
+ dl_error_ = error;
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, NewRunnableMethod(
+ this, &DownloadsDownloadFunction::RespondOnUIThread));
+}
+
+void DownloadsDownloadFunction::RespondOnUIThread() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ VLOG(1) << __FUNCTION__ << " " << url_ << " " << dl_man_ << " " << filename_
+ << " " << dl_id_ << " " << dl_error_ << " " << method_;
+ if (dl_id_ >= 0) {
+ products_->Set("id", Value::CreateIntegerValue(dl_id_));
+ } else {
+ products_->Set("error", Value::CreateIntegerValue(dl_error_));
+ }
+ SendResponse(true);
+}
+
+bool DownloadsSearchFunction::RunImpl() {
+ DictionaryValue* query_json = NULL;
+ EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &query_json));
+ CHECK(query_json);
+ download_util::DownloadQuery query(*query_json);
+ DownloadManager* dlman = profile()->GetDownloadManager();
+ if (dlman == NULL) {
+ error_ = "I'm afraid I can't do that.";
+ return false;
+ }
+ ListValue* results = new ListValue();
+ if (!dlman->Search(
+ download_util::DownloadQuery(*query_json),
+ NULL/*DownloadItem results*/,
+ true/*merge_parent_manager*/,
+ &error_,
+ results)) {
+ VLOG(1) << __PRETTY_FUNCTION__ << " " << error_;
+ return false;
+ }
+ result_.reset(results);
+ return true;
+}
+
+bool DownloadsPauseFunction::RunImpl() {
+ int dl_id = 0;
+ EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &dl_id));
+ DownloadManager* dlman = profile()->GetDownloadManager();
+ if (dlman == NULL) {
+ error_ = "I'm afraid I can't do that.";
+ return false;
+ }
+ DownloadItem* item = dlman->GetDownloadItem(dl_id);
+ if (item == NULL) {
+ error_ = "Non-existent download";
+ return false;
+ }
+ VLOG(1) << __FUNCTION__ << " " << item;
+ if (!item->is_paused()) {
+ item->TogglePause();
+ }
+ return true;
+}
+
+bool DownloadsResumeFunction::RunImpl() {
+ int dl_id = 0;
+ EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &dl_id));
+ DownloadManager* dlman = profile()->GetDownloadManager();
+ if (dlman == NULL) {
+ error_ = "I'm afraid I can't do that.";
+ return false;
+ }
+ DownloadItem* item = dlman->GetDownloadItem(dl_id);
+ if (item == NULL) {
+ error_ = "Non-existent download";
+ return false;
+ }
+ VLOG(1) << __FUNCTION__ << " " << item;
+ if (item->is_paused()) {
+ item->TogglePause();
+ }
+ return true;
+}
+
+bool DownloadsCancelFunction::RunImpl() {
+ int dl_id = 0;
+ EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &dl_id));
+ DownloadManager* dlman = profile()->GetDownloadManager();
+ if (dlman == NULL) {
+ error_ = "I'm afraid I can't do that.";
+ return false;
+ }
+ DownloadItem* item = dlman->GetDownloadItem(dl_id);
+ if (item == NULL) {
+ error_ = "Non-existent download";
+ return false;
+ }
+ VLOG(1) << __FUNCTION__ << " " << item;
+ item->Cancel(true);
+ return true;
+}
+
+bool DownloadsEraseFunction::RunImpl() {
+ return true;
+}
+
+bool DownloadsSetDestinationFunction::RunImpl() {
+ int dl_id = 0;
+ std::string rel_dest_path;
+ if ((args_.get() == NULL) ||
+ (args_->GetSize() < 2) ||
+ !args_->GetInteger(0, &dl_id) ||
+ (dl_id == 0) ||
+ !args_->GetString(1, &rel_dest_path) ||
+ rel_dest_path.empty()) return false;
+ DownloadManager* dlman = profile()->GetDownloadManager();
+ DownloadItem* item = dlman->GetDownloadItem(dl_id);
+ if (item == NULL) return false;
+ VLOG(1) << __FUNCTION__ << " " << dl_id << " " << item << " "
+ << rel_dest_path;
+ return true;
+}
+
+bool DownloadsAcceptDangerFunction::RunImpl() {
+ int dl_id = 0;
+ EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &dl_id));
+ DownloadManager* dlman = profile()->GetDownloadManager();
+ if (dlman == NULL) {
+ error_ = "I'm afraid I can't do that.";
+ return false;
+ }
+ DownloadItem* item = dlman->GetDownloadItem(dl_id);
+ if (item == NULL) {
+ error_ = "Non-existent download";
+ return false;
+ }
+ VLOG(1) << __FUNCTION__ << " " << item;
+ item->Cancel(true);
+ return true;
+}
+
+bool DownloadsShowFunction::RunImpl() {
+ int dl_id = 0;
+ if ((args_.get() == NULL) ||
+ (args_->GetSize() < 1) ||
+ !args_->GetInteger(0, &dl_id) ||
+ (dl_id == 0)) return false;
+ DownloadManager* dlman = profile()->GetDownloadManager();
+ DownloadItem* item = dlman->GetDownloadItem(dl_id);
+ if (item == NULL) return false;
+ VLOG(1) << __FUNCTION__ << " " << item;
+ return true;
+}
+
+bool DownloadsDragFunction::RunImpl() {
+ int dl_id = 0;
+ if ((args_.get() == NULL) ||
+ (args_->GetSize() < 1) ||
+ !args_->GetInteger(0, &dl_id) ||
+ (dl_id == 0)) return false;
+ DownloadManager* dlman = profile()->GetDownloadManager();
+ DownloadItem* item = dlman->GetDownloadItem(dl_id);
+ if (item == NULL) return false;
+ IconManager* im = g_browser_process->icon_manager();
+ gfx::Image* icon = im->LookupIcon(item->GetUserVerifiedFilePath(),
+ IconLoader::NORMAL);
+ gfx::NativeView view = BrowserList::GetLastActive()
+ ->GetSelectedTabContentsWrapper()->tab_contents()->GetNativeView();
+ download_util::DragDownload(item, icon, view);
+ VLOG(1) << __FUNCTION__ << " " << dl_id;
+ return true;
+}
+
+struct DownloadsEventRouter::EventListener {
+ std::string ext_id;
+ base::WeakPtr<IPC::Message::Sender> ipc_sender;
+
+ EventListener(std::string eid, base::WeakPtr<IPC::Message::Sender> ipcs)
+ : ext_id(eid),
+ ipc_sender(ipcs) {
+ }
+ ~EventListener() {}
+
+ void SendEvent() {
+ }
+
+ // Comparator to work with std::set.
+ bool operator<(const EventListener& that) const {
+ return ext_id < that.ext_id;
+ }
+
+ // Allow copy and assign.
+};
+
+class DownloadsEventRouter::ManagerObserver
+ : public DownloadManager::Observer {
+ public:
+ ManagerObserver(DownloadsEventRouter* router,
+ ProfileId profile_id,
+ DownloadManager* manager)
+ : router_(router),
+ profile_id_(profile_id),
+ manager_(manager) {
+ DCHECK(router);
+ DCHECK(manager_);
+ manager_->AddObserver(this);
+ }
+ ~ManagerObserver() {
+ if (manager_) manager_->RemoveObserver(this);
+ }
+
+ virtual void ModelChanged() {
+ DCHECK(manager_);
+ DVLOG(1) << __FUNCTION__ << " " << manager_ << " " << profile_id_ << " " << router_;
+ router_->DispatchEvent(DownloadsEventRouter::CHANGED, profile_id_, 0);
+ }
+
+ virtual void ManagerGoingDown() {
+ manager_ = NULL;
+ }
+
+ private:
+ DownloadsEventRouter* router_;
+ ProfileId profile_id_;
+ DownloadManager* manager_;
+
+ DISALLOW_COPY_AND_ASSIGN(ManagerObserver);
+};
+
+class DownloadsEventRouter::ItemObserver : public DownloadItem::Observer {
+ public:
+ ItemObserver() {}
+ ~ItemObserver() {}
+
+ virtual void OnDownloadUpdated(DownloadItem* download) {
+ DVLOG(1) << __FUNCTION__ << " " << download->id();
+ }
+
+ virtual void OnDownloadOpened(DownloadItem* download) {
+ DVLOG(1) << __FUNCTION__ << " " << download->id();
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ItemObserver);
+};
+
+DownloadsEventRouter::DownloadsEventRouter() {
+}
+
+DownloadsEventRouter::~DownloadsEventRouter() {
+}
+
+DownloadsEventRouter* DownloadsEventRouter::GetInstance() {
+ return Singleton<DownloadsEventRouter>::get();
+}
+
+void DownloadsEventRouter::AddEventListener(
+ EventType event_type,
+ ProfileId profile_id,
+ const std::string& extension_id,
+ base::WeakPtr<IPC::Message::Sender> ipc_sender) {
+ DVLOG(1) << __FUNCTION__
+ << " " << event_type
+ << " " << profile_id
+ << " " << extension_id
+ << " " << BrowserThread::CurrentlyOn(BrowserThread::UI);
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ DCHECK(BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ NewRunnableMethod(this, &DownloadsEventRouter::AddEventListener,
+ event_type, profile_id, extension_id, ipc_sender)));
+ return;
+ }
+ Profile* profile = reinterpret_cast<Profile*>(profile_id); // XXX
+ DownloadManager* dlman = profile->GetDownloadManager();
+ DCHECK(dlman);
+ listeners_[profile_id][event_type].insert(EventListener(
+ extension_id, ipc_sender));
+ if (manager_observers_.find(profile_id) == manager_observers_.end()) {
+ manager_observers_[profile_id] = new ManagerObserver(this, profile_id, dlman);
+ }
+}
+
+void DownloadsEventRouter::DispatchEvent(
+ EventType event_type,
+ ProfileId profile_id,
+ int download_id) {
+ DVLOG(1) << __FUNCTION__
+ << " " << event_type
+ << " " << profile_id
+ << " " << download_id
+ << " " << BrowserThread::CurrentlyOn(BrowserThread::IO);
+ if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
+ DCHECK(BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ NewRunnableMethod(this, &DownloadsEventRouter::DispatchEvent,
+ event_type, profile_id, download_id)));
+ return;
+ }
+ LOG(ERROR) << __FUNCTION__ << " " << event_type << " " << profile_id << " " << download_id;
+ if (event_type == CREATED) {
+ //item_observers_[profile_id].insert(ItemObserver(this, profile_id));
+ } else if (event_type == ERASED) {
+ //item_observers_[profile_id];
+ }
+ const ListenerSet& listeners = listeners_[profile_id][event_type];
+ for (ListenerSet::iterator listener = listeners.begin();
+ listener != listeners.end(); ++listener) {
+ //(*listener)->ipc_sender->Send(new ExtensionMsg_MessageInvoke(
+ //MSG_ROUTING_CONTROL, (*listener)->ext_id, kDispatchEvent, args, event_url));
+ //ExtensionEventRouter::DispatchEvent(
+ // (*listener)->ipc_sender.get(), (*listener)->ext_id, (*it)->sub_event_name,
+ // json_args, GURL());
+ }
+}
« no previous file with comments | « chrome/browser/extensions/extension_downloads.h ('k') | chrome/browser/extensions/extension_event_names.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698