summaryrefslogtreecommitdiffstats
path: root/chrome/browser/ui/webui/downloads_dom_handler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/ui/webui/downloads_dom_handler.cc')
-rw-r--r--chrome/browser/ui/webui/downloads_dom_handler.cc248
1 files changed, 248 insertions, 0 deletions
diff --git a/chrome/browser/ui/webui/downloads_dom_handler.cc b/chrome/browser/ui/webui/downloads_dom_handler.cc
new file mode 100644
index 0000000..49a9fc0
--- /dev/null
+++ b/chrome/browser/ui/webui/downloads_dom_handler.cc
@@ -0,0 +1,248 @@
+// 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/ui/webui/downloads_dom_handler.h"
+
+#include <algorithm>
+#include <functional>
+
+#include "base/basictypes.h"
+#include "base/callback.h"
+#include "base/singleton.h"
+#include "base/string_piece.h"
+#include "base/threading/thread.h"
+#include "base/utf_string_conversions.h"
+#include "base/values.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/browser_thread.h"
+#include "chrome/browser/download/download_history.h"
+#include "chrome/browser/download/download_item.h"
+#include "chrome/browser/download/download_util.h"
+#include "chrome/browser/metrics/user_metrics.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/ui/webui/chrome_url_data_manager.h"
+#include "chrome/browser/ui/webui/fileicon_source.h"
+#include "chrome/common/jstemplate_builder.h"
+#include "chrome/common/url_constants.h"
+#include "grit/generated_resources.h"
+
+namespace {
+
+// Maximum number of downloads to show. TODO(glen): Remove this and instead
+// stuff the downloads down the pipe slowly.
+static const int kMaxDownloads = 150;
+
+// Sort DownloadItems into descending order by their start time.
+class DownloadItemSorter : public std::binary_function<DownloadItem*,
+ DownloadItem*,
+ bool> {
+ public:
+ bool operator()(const DownloadItem* lhs, const DownloadItem* rhs) {
+ return lhs->start_time() > rhs->start_time();
+ }
+};
+
+} // namespace
+
+DownloadsDOMHandler::DownloadsDOMHandler(DownloadManager* dlm)
+ : search_text_(),
+ download_manager_(dlm),
+ callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+ // Create our fileicon data source.
+ dlm->profile()->GetChromeURLDataManager()->AddDataSource(
+ new FileIconSource());
+}
+
+DownloadsDOMHandler::~DownloadsDOMHandler() {
+ ClearDownloadItems();
+ download_manager_->RemoveObserver(this);
+}
+
+// DownloadsDOMHandler, public: -----------------------------------------------
+
+void DownloadsDOMHandler::Init() {
+ download_manager_->AddObserver(this);
+}
+
+void DownloadsDOMHandler::RegisterMessages() {
+ web_ui_->RegisterMessageCallback("getDownloads",
+ NewCallback(this, &DownloadsDOMHandler::HandleGetDownloads));
+ web_ui_->RegisterMessageCallback("openFile",
+ NewCallback(this, &DownloadsDOMHandler::HandleOpenFile));
+
+ web_ui_->RegisterMessageCallback("drag",
+ NewCallback(this, &DownloadsDOMHandler::HandleDrag));
+
+ web_ui_->RegisterMessageCallback("saveDangerous",
+ NewCallback(this, &DownloadsDOMHandler::HandleSaveDangerous));
+ web_ui_->RegisterMessageCallback("discardDangerous",
+ NewCallback(this, &DownloadsDOMHandler::HandleDiscardDangerous));
+ web_ui_->RegisterMessageCallback("show",
+ NewCallback(this, &DownloadsDOMHandler::HandleShow));
+ web_ui_->RegisterMessageCallback("togglepause",
+ NewCallback(this, &DownloadsDOMHandler::HandlePause));
+ web_ui_->RegisterMessageCallback("resume",
+ NewCallback(this, &DownloadsDOMHandler::HandlePause));
+ web_ui_->RegisterMessageCallback("remove",
+ NewCallback(this, &DownloadsDOMHandler::HandleRemove));
+ web_ui_->RegisterMessageCallback("cancel",
+ NewCallback(this, &DownloadsDOMHandler::HandleCancel));
+ web_ui_->RegisterMessageCallback("clearAll",
+ NewCallback(this, &DownloadsDOMHandler::HandleClearAll));
+}
+
+void DownloadsDOMHandler::OnDownloadUpdated(DownloadItem* download) {
+ // Get the id for the download. Our downloads are sorted latest to first,
+ // and the id is the index into that list. We should be careful of sync
+ // errors between the UI and the download_items_ list (we may wish to use
+ // something other than 'id').
+ OrderedDownloads::iterator it = find(download_items_.begin(),
+ download_items_.end(),
+ download);
+ if (it == download_items_.end())
+ return;
+ const int id = static_cast<int>(it - download_items_.begin());
+
+ ListValue results_value;
+ results_value.Append(download_util::CreateDownloadItemValue(download, id));
+ web_ui_->CallJavascriptFunction(L"downloadUpdated", results_value);
+}
+
+// A download has started or been deleted. Query our DownloadManager for the
+// current set of downloads.
+void DownloadsDOMHandler::ModelChanged() {
+ ClearDownloadItems();
+ download_manager_->SearchDownloads(WideToUTF16(search_text_),
+ &download_items_);
+ sort(download_items_.begin(), download_items_.end(), DownloadItemSorter());
+
+ // Scan for any in progress downloads and add ourself to them as an observer.
+ for (OrderedDownloads::iterator it = download_items_.begin();
+ it != download_items_.end(); ++it) {
+ if (static_cast<int>(it - download_items_.begin()) > kMaxDownloads)
+ break;
+
+ DownloadItem* download = *it;
+ if (download->state() == DownloadItem::IN_PROGRESS) {
+ // We want to know what happens as the download progresses.
+ download->AddObserver(this);
+ } else if (download->safety_state() == DownloadItem::DANGEROUS) {
+ // We need to be notified when the user validates the dangerous download.
+ download->AddObserver(this);
+ }
+ }
+
+ SendCurrentDownloads();
+}
+
+void DownloadsDOMHandler::HandleGetDownloads(const ListValue* args) {
+ std::wstring new_search = ExtractStringValue(args);
+ if (search_text_.compare(new_search) != 0) {
+ search_text_ = new_search;
+ ModelChanged();
+ } else {
+ SendCurrentDownloads();
+ }
+}
+
+void DownloadsDOMHandler::HandleOpenFile(const ListValue* args) {
+ DownloadItem* file = GetDownloadByValue(args);
+ if (file)
+ file->OpenDownload();
+}
+
+void DownloadsDOMHandler::HandleDrag(const ListValue* args) {
+ DownloadItem* file = GetDownloadByValue(args);
+ if (file) {
+ IconManager* im = g_browser_process->icon_manager();
+ SkBitmap* icon = im->LookupIcon(file->GetUserVerifiedFilePath(),
+ IconLoader::NORMAL);
+ gfx::NativeView view = web_ui_->tab_contents()->GetNativeView();
+ download_util::DragDownload(file, icon, view);
+ }
+}
+
+void DownloadsDOMHandler::HandleSaveDangerous(const ListValue* args) {
+ DownloadItem* file = GetDownloadByValue(args);
+ if (file)
+ download_manager_->DangerousDownloadValidated(file);
+}
+
+void DownloadsDOMHandler::HandleDiscardDangerous(const ListValue* args) {
+ DownloadItem* file = GetDownloadByValue(args);
+ if (file)
+ file->Remove(true);
+}
+
+void DownloadsDOMHandler::HandleShow(const ListValue* args) {
+ DownloadItem* file = GetDownloadByValue(args);
+ if (file)
+ file->ShowDownloadInShell();
+}
+
+void DownloadsDOMHandler::HandlePause(const ListValue* args) {
+ DownloadItem* file = GetDownloadByValue(args);
+ if (file)
+ file->TogglePause();
+}
+
+void DownloadsDOMHandler::HandleRemove(const ListValue* args) {
+ DownloadItem* file = GetDownloadByValue(args);
+ if (file)
+ file->Remove(false);
+}
+
+void DownloadsDOMHandler::HandleCancel(const ListValue* args) {
+ DownloadItem* file = GetDownloadByValue(args);
+ if (file)
+ file->Cancel(true);
+}
+
+void DownloadsDOMHandler::HandleClearAll(const ListValue* args) {
+ download_manager_->RemoveAllDownloads();
+}
+
+// DownloadsDOMHandler, private: ----------------------------------------------
+
+void DownloadsDOMHandler::SendCurrentDownloads() {
+ ListValue results_value;
+ for (OrderedDownloads::iterator it = download_items_.begin();
+ it != download_items_.end(); ++it) {
+ int index = static_cast<int>(it - download_items_.begin());
+ if (index > kMaxDownloads)
+ break;
+ results_value.Append(download_util::CreateDownloadItemValue(*it, index));
+ }
+
+ web_ui_->CallJavascriptFunction(L"downloadsList", results_value);
+}
+
+void DownloadsDOMHandler::ClearDownloadItems() {
+ // Clear out old state and remove self as observer for each download.
+ for (OrderedDownloads::iterator it = download_items_.begin();
+ it != download_items_.end(); ++it) {
+ (*it)->RemoveObserver(this);
+ }
+ download_items_.clear();
+}
+
+DownloadItem* DownloadsDOMHandler::GetDownloadById(int id) {
+ for (OrderedDownloads::iterator it = download_items_.begin();
+ it != download_items_.end(); ++it) {
+ if (static_cast<int>(it - download_items_.begin() == id)) {
+ return (*it);
+ }
+ }
+
+ return NULL;
+}
+
+DownloadItem* DownloadsDOMHandler::GetDownloadByValue(const ListValue* args) {
+ int id;
+ if (ExtractIntegerValue(args, &id)) {
+ return GetDownloadById(id);
+ }
+ return NULL;
+}