| Index: chrome/browser/dom_ui/downloads_ui.cc
|
| ===================================================================
|
| --- chrome/browser/dom_ui/downloads_ui.cc (revision 0)
|
| +++ chrome/browser/dom_ui/downloads_ui.cc (revision 0)
|
| @@ -0,0 +1,361 @@
|
| +// Copyright (c) 2006-2008 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/dom_ui/downloads_ui.h"
|
| +
|
| +#include "base/gfx/png_encoder.h"
|
| +#include "base/string_piece.h"
|
| +#include "base/thread.h"
|
| +#include "base/time.h"
|
| +#include "base/time_format.h"
|
| +#include "chrome/browser/browser_process.h"
|
| +#include "chrome/browser/dom_ui/fileicon_source.h"
|
| +#include "chrome/browser/download/download_util.h"
|
| +#include "chrome/browser/metrics/user_metrics.h"
|
| +#include "chrome/browser/profile.h"
|
| +#include "chrome/common/jstemplate_builder.h"
|
| +#include "chrome/common/l10n_util.h"
|
| +#include "chrome/common/time_format.h"
|
| +
|
| +// Generated by GRIT
|
| +#include "browser_resources.h"
|
| +#include "generated_resources.h"
|
| +
|
| +using base::Time;
|
| +
|
| +// DownloadsUI is accessible from chrome-ui://downloads.
|
| +static const char kDownloadsHost[] = "downloads";
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +//
|
| +// DownloadsHTMLSource
|
| +//
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +
|
| +DownloadsUIHTMLSource::DownloadsUIHTMLSource()
|
| + : DataSource(kDownloadsHost, MessageLoop::current()) {
|
| +}
|
| +
|
| +void DownloadsUIHTMLSource::StartDataRequest(const std::string& path,
|
| + int request_id) {
|
| + DictionaryValue localized_strings;
|
| + localized_strings.SetString(L"title",
|
| + l10n_util::GetString(IDS_DOWNLOAD_TITLE));
|
| + localized_strings.SetString(L"searchbutton",
|
| + l10n_util::GetString(IDS_DOWNLOAD_SEARCH_BUTTON));
|
| + localized_strings.SetString(L"no_results",
|
| + l10n_util::GetString(IDS_DOWNLOAD_SEARCH_BUTTON));
|
| + localized_strings.SetString(L"searchresultsfor",
|
| + l10n_util::GetString(IDS_DOWNLOAD_SEARCHRESULTSFOR));
|
| + localized_strings.SetString(L"downloads",
|
| + l10n_util::GetString(IDS_DOWNLOAD_TITLE));
|
| +
|
| + // Status.
|
| + localized_strings.SetString(L"status_cancelled",
|
| + l10n_util::GetString(IDS_DOWNLOAD_TAB_CANCELLED));
|
| + localized_strings.SetString(L"status_paused",
|
| + l10n_util::GetString(IDS_DOWNLOAD_PROGRESS_PAUSED));
|
| +
|
| + // Dangerous file.
|
| + localized_strings.SetString(L"danger_desc",
|
| + l10n_util::GetStringF(IDS_PROMPT_DANGEROUS_DOWNLOAD, L"%s"));
|
| + localized_strings.SetString(L"danger_save",
|
| + l10n_util::GetString(IDS_SAVE_DOWNLOAD));
|
| + localized_strings.SetString(L"danger_discard",
|
| + l10n_util::GetString(IDS_DISCARD_DOWNLOAD));
|
| +
|
| + // Controls.
|
| + localized_strings.SetString(L"control_pause",
|
| + l10n_util::GetString(IDS_DOWNLOAD_LINK_PAUSE));
|
| + localized_strings.SetString(L"control_showinfolder",
|
| + l10n_util::GetString(IDS_DOWNLOAD_LINK_SHOW));
|
| + localized_strings.SetString(L"control_cancel",
|
| + l10n_util::GetString(IDS_DOWNLOAD_LINK_CANCEL));
|
| + localized_strings.SetString(L"control_resume",
|
| + l10n_util::GetString(IDS_DOWNLOAD_LINK_RESUME));
|
| +
|
| + static const StringPiece downloads_html(
|
| + ResourceBundle::GetSharedInstance().GetRawDataResource(
|
| + IDR_DOWNLOADS_HTML));
|
| + const std::string full_html = jstemplate_builder::GetTemplateHtml(
|
| + downloads_html, &localized_strings, "t");
|
| +
|
| + scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes);
|
| + html_bytes->data.resize(full_html.size());
|
| + std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin());
|
| +
|
| + SendResponse(request_id, html_bytes);
|
| +}
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +//
|
| +// DownloadsDOMHandler
|
| +//
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +
|
| +// 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();
|
| + }
|
| +};
|
| +
|
| +DownloadsDOMHandler::DownloadsDOMHandler(DOMUI* dom_ui, DownloadManager* dlm)
|
| + : DOMMessageHandler(dom_ui),
|
| + download_manager_(dlm),
|
| + search_text_() {
|
| + dom_ui_->RegisterMessageCallback("getDownloads",
|
| + NewCallback(this, &DownloadsDOMHandler::HandleGetDownloads));
|
| + dom_ui_->RegisterMessageCallback("openFile",
|
| + NewCallback(this, &DownloadsDOMHandler::HandleOpenFile));
|
| +
|
| + dom_ui_->RegisterMessageCallback("drag",
|
| + NewCallback(this, &DownloadsDOMHandler::HandleDrag));
|
| +
|
| + dom_ui_->RegisterMessageCallback("saveDangerous",
|
| + NewCallback(this, &DownloadsDOMHandler::HandleSaveDangerous));
|
| + dom_ui_->RegisterMessageCallback("discardDangerous",
|
| + NewCallback(this, &DownloadsDOMHandler::HandleDiscardDangerous));
|
| + dom_ui_->RegisterMessageCallback("show",
|
| + NewCallback(this, &DownloadsDOMHandler::HandleShow));
|
| + dom_ui_->RegisterMessageCallback("pause",
|
| + NewCallback(this, &DownloadsDOMHandler::HandlePause));
|
| + dom_ui_->RegisterMessageCallback("cancel",
|
| + NewCallback(this, &DownloadsDOMHandler::HandleCancel));
|
| +
|
| + // Create our fileicon data source.
|
| + g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE,
|
| + NewRunnableMethod(&chrome_url_data_manager,
|
| + &ChromeURLDataManager::AddDataSource,
|
| + new FileIconSource()));
|
| +}
|
| +
|
| +DownloadsDOMHandler::~DownloadsDOMHandler() {
|
| + ClearDownloadItems();
|
| + download_manager_->RemoveObserver(this);
|
| +}
|
| +
|
| +// DownloadsDOMHandler, public: -----------------------------------------------
|
| +
|
| +void DownloadsDOMHandler::Init() {
|
| + download_manager_->AddObserver(this);
|
| +}
|
| +
|
| +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(CreateDownloadItemValue(download, id));
|
| + dom_ui_->CallJavascriptFunction(L"downloadUpdated", results_value);
|
| +}
|
| +
|
| +// A download has started or been deleted. Query our DownloadManager for the
|
| +// current set of downloads, which will call us back in SetDownloads once it
|
| +// has retrieved them.
|
| +void DownloadsDOMHandler::ModelChanged() {
|
| + ClearDownloadItems();
|
| + download_manager_->GetDownloads(this, search_text_);
|
| +}
|
| +
|
| +void DownloadsDOMHandler::SetDownloads(
|
| + std::vector<DownloadItem*>& downloads) {
|
| + ClearDownloadItems();
|
| +
|
| + // Swap new downloads in.
|
| + download_items_.swap(downloads);
|
| + 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) {
|
| + 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 Value* value) {
|
| + std::wstring new_search = ExtractStringValue(value);
|
| + if (search_text_.compare(new_search) != 0) {
|
| + search_text_ = new_search;
|
| + ClearDownloadItems();
|
| + download_manager_->GetDownloads(this, search_text_);
|
| + } else {
|
| + SendCurrentDownloads();
|
| + }
|
| +}
|
| +
|
| +void DownloadsDOMHandler::HandleOpenFile(const Value* value) {
|
| + DownloadItem* file = GetDownloadById(ExtractIntegerValue(value));
|
| + if (file)
|
| + download_manager_->OpenDownloadInShell(file, NULL);
|
| +}
|
| +
|
| +void DownloadsDOMHandler::HandleDrag(const Value* value) {
|
| + DownloadItem* file = GetDownloadById(ExtractIntegerValue(value));
|
| + if (file) {
|
| + IconManager* im = g_browser_process->icon_manager();
|
| + SkBitmap* icon = im->LookupIcon(file->full_path().ToWStringHack(),
|
| + IconLoader::NORMAL);
|
| + download_util::DragDownload(file, icon);
|
| + }
|
| +}
|
| +
|
| +void DownloadsDOMHandler::HandleSaveDangerous(const Value* value) {
|
| + DownloadItem* file = GetDownloadById(ExtractIntegerValue(value));
|
| + if (file)
|
| + download_manager_->DangerousDownloadValidated(file);
|
| +}
|
| +
|
| +void DownloadsDOMHandler::HandleDiscardDangerous(const Value* value) {
|
| + DownloadItem* file = GetDownloadById(ExtractIntegerValue(value));
|
| + if (file)
|
| + file->Remove(true);
|
| +}
|
| +
|
| +void DownloadsDOMHandler::HandleShow(const Value* value) {
|
| + DownloadItem* file = GetDownloadById(ExtractIntegerValue(value));
|
| + if (file)
|
| + download_manager_->ShowDownloadInShell(file);
|
| +}
|
| +
|
| +void DownloadsDOMHandler::HandlePause(const Value* value) {
|
| + DownloadItem* file = GetDownloadById(ExtractIntegerValue(value));
|
| + if (file)
|
| + file->TogglePause();
|
| +}
|
| +
|
| +void DownloadsDOMHandler::HandleCancel(const Value* value) {
|
| + DownloadItem* file = GetDownloadById(ExtractIntegerValue(value));
|
| + if (file)
|
| + file->Cancel(true);
|
| +}
|
| +
|
| +// DownloadsDOMHandler, private: ----------------------------------------------
|
| +
|
| +void DownloadsDOMHandler::SendCurrentDownloads() {
|
| + ListValue results_value;
|
| +
|
| + for (OrderedDownloads::iterator it = download_items_.begin();
|
| + it != download_items_.end(); ++it) {
|
| + results_value.Append(CreateDownloadItemValue(*it,
|
| + static_cast<int>(it - download_items_.begin())));
|
| + }
|
| +
|
| + dom_ui_->CallJavascriptFunction(L"downloadsList", results_value);
|
| +}
|
| +
|
| +DictionaryValue* DownloadsDOMHandler::CreateDownloadItemValue(
|
| + DownloadItem* download, int id) {
|
| + DictionaryValue* file_value = new DictionaryValue();
|
| +
|
| + file_value->SetInteger(L"time",
|
| + static_cast<int>(download->start_time().ToTimeT()));
|
| + file_value->SetInteger(L"id", id);
|
| + file_value->SetString(L"file_path", download->full_path().ToWStringHack());
|
| + file_value->SetString(L"file_name", download->GetFileName().ToWStringHack());
|
| + file_value->SetString(L"url", download->url().spec());
|
| +
|
| + if (download->state() == DownloadItem::IN_PROGRESS) {
|
| + if (download->safety_state() == DownloadItem::DANGEROUS) {
|
| + file_value->SetString(L"state", L"DANGEROUS");
|
| + } else if (download->is_paused()) {
|
| + file_value->SetString(L"state", L"PAUSED");
|
| + } else {
|
| + file_value->SetString(L"state", L"IN_PROGRESS");
|
| + }
|
| + file_value->SetInteger(L"speed",
|
| + static_cast<int>(download->CurrentSpeed()));
|
| + file_value->SetInteger(L"percent",
|
| + static_cast<int>(download->PercentComplete()));
|
| + file_value->SetInteger(L"received",
|
| + static_cast<int>(download->received_bytes()));
|
| + } else if (download->state() == DownloadItem::CANCELLED) {
|
| + file_value->SetString(L"state", L"CANCELLED");
|
| + } else if (download->state() == DownloadItem::COMPLETE) {
|
| + if (download->safety_state() == DownloadItem::DANGEROUS) {
|
| + file_value->SetString(L"state", L"DANGEROUS");
|
| + } else {
|
| + file_value->SetString(L"state", L"COMPLETE");
|
| + }
|
| + }
|
| +
|
| + file_value->SetInteger(L"total",
|
| + static_cast<int>(download->total_bytes()));
|
| +
|
| + return file_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;
|
| +}
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +//
|
| +// DownloadsUI
|
| +//
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +
|
| +DownloadsUI::DownloadsUI(DOMUIContents* contents) : DOMUI(contents) {
|
| +}
|
| +
|
| +void DownloadsUI::Init() {
|
| + DownloadManager* dlm = get_profile()->GetDownloadManager();
|
| +
|
| + DownloadsDOMHandler* handler = new DownloadsDOMHandler(this, dlm);
|
| + AddMessageHandler(handler);
|
| + handler->Init();
|
| +
|
| + DownloadsUIHTMLSource* html_source = new DownloadsUIHTMLSource();
|
| +
|
| + // Set up the chrome-ui://downloads/ source.
|
| + g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE,
|
| + NewRunnableMethod(&chrome_url_data_manager,
|
| + &ChromeURLDataManager::AddDataSource,
|
| + html_source));
|
| +}
|
| +
|
| +// static
|
| +GURL DownloadsUI::GetBaseURL() {
|
| + std::string url = DOMUIContents::GetScheme();
|
| + url += "://";
|
| + url += kDownloadsHost;
|
| + return GURL(url);
|
| +}
|
| +
|
|
|