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

Side by Side Diff: chrome/browser/ui/webui/downloads_dom_handler.cc

Issue 966983002: downloads: clicking "remove" on chrome://downloads should also hide shelf item. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: +tests Created 5 years, 9 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 unified diff | Download patch
OLDNEW
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/ui/webui/downloads_dom_handler.h" 5 #include "chrome/browser/ui/webui/downloads_dom_handler.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <functional> 8 #include <functional>
9 9
10 #include "base/basictypes.h" 10 #include "base/basictypes.h"
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 DOWNLOADS_DOM_EVENT_SHOW = 5, 70 DOWNLOADS_DOM_EVENT_SHOW = 5,
71 DOWNLOADS_DOM_EVENT_PAUSE = 6, 71 DOWNLOADS_DOM_EVENT_PAUSE = 6,
72 DOWNLOADS_DOM_EVENT_REMOVE = 7, 72 DOWNLOADS_DOM_EVENT_REMOVE = 7,
73 DOWNLOADS_DOM_EVENT_CANCEL = 8, 73 DOWNLOADS_DOM_EVENT_CANCEL = 8,
74 DOWNLOADS_DOM_EVENT_CLEAR_ALL = 9, 74 DOWNLOADS_DOM_EVENT_CLEAR_ALL = 9,
75 DOWNLOADS_DOM_EVENT_OPEN_FOLDER = 10, 75 DOWNLOADS_DOM_EVENT_OPEN_FOLDER = 10,
76 DOWNLOADS_DOM_EVENT_RESUME = 11, 76 DOWNLOADS_DOM_EVENT_RESUME = 11,
77 DOWNLOADS_DOM_EVENT_MAX 77 DOWNLOADS_DOM_EVENT_MAX
78 }; 78 };
79 79
80 static const char kKey[] = "DownloadsDOMHandlerData";
81
82 class DownloadsDOMHandlerData : public base::SupportsUserData::Data {
83 public:
84 static DownloadsDOMHandlerData* Get(content::DownloadItem* item) {
85 return static_cast<DownloadsDOMHandlerData*>(item->GetUserData(kKey));
86 }
87
88 static const DownloadsDOMHandlerData* Get(const content::DownloadItem* item) {
89 return static_cast<DownloadsDOMHandlerData*>(item->GetUserData(kKey));
90 }
91
92 static void Set(content::DownloadItem* item, DownloadsDOMHandlerData* data) {
93 item->SetUserData(kKey, data);
94 }
95
96 static DownloadsDOMHandlerData* Create(content::DownloadItem* item) {
97 DownloadsDOMHandlerData* data = new DownloadsDOMHandlerData;
98 item->SetUserData(kKey, data);
99 return data;
100 }
101
102 void set_is_removed(bool is_removed) { is_removed_ = is_removed; }
103 bool is_removed() const { return is_removed_; }
104
105 private:
106 bool is_removed_;
107 };
108
109 void CountDownloadsDOMEvents(DownloadsDOMEvent event) { 80 void CountDownloadsDOMEvents(DownloadsDOMEvent event) {
110 UMA_HISTOGRAM_ENUMERATION("Download.DOMEvent", 81 UMA_HISTOGRAM_ENUMERATION("Download.DOMEvent",
111 event, 82 event,
112 DOWNLOADS_DOM_EVENT_MAX); 83 DOWNLOADS_DOM_EVENT_MAX);
113 } 84 }
114 85
115 // Returns a string constant to be used as the |danger_type| value in 86 // Returns a string constant to be used as the |danger_type| value in
116 // CreateDownloadItemValue(). Only return strings for DANGEROUS_FILE, 87 // CreateDownloadItemValue(). Only return strings for DANGEROUS_FILE,
117 // DANGEROUS_URL, DANGEROUS_CONTENT, and UNCOMMON_CONTENT because the 88 // DANGEROUS_URL, DANGEROUS_CONTENT, and UNCOMMON_CONTENT because the
118 // |danger_type| value is only defined if the value of |state| is |DANGEROUS|. 89 // |danger_type| value is only defined if the value of |state| is |DANGEROUS|.
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 file_value->SetString("state", "COMPLETE"); 231 file_value->SetString("state", "COMPLETE");
261 break; 232 break;
262 233
263 case content::DownloadItem::MAX_DOWNLOAD_STATE: 234 case content::DownloadItem::MAX_DOWNLOAD_STATE:
264 NOTREACHED(); 235 NOTREACHED();
265 } 236 }
266 237
267 return file_value; 238 return file_value;
268 } 239 }
269 240
270 bool IsRemoved(const content::DownloadItem& item) {
271 const DownloadsDOMHandlerData* data = DownloadsDOMHandlerData::Get(&item);
272 return data && data->is_removed();
273 }
274
275 // Filters out extension downloads and downloads that don't have a filename yet. 241 // Filters out extension downloads and downloads that don't have a filename yet.
276 bool IsDownloadDisplayable(const content::DownloadItem& item) { 242 bool IsDownloadDisplayable(const content::DownloadItem& item) {
277 return !download_crx_util::IsExtensionDownload(item) && 243 return !download_crx_util::IsExtensionDownload(item) &&
278 !item.IsTemporary() && 244 !item.IsTemporary() &&
279 !item.GetFileNameToReportUser().empty() && 245 !item.GetFileNameToReportUser().empty() &&
280 !item.GetTargetFilePath().empty() && 246 !item.GetTargetFilePath().empty() &&
281 !IsRemoved(item); 247 DownloadItemModel(
248 const_cast<content::DownloadItem*>(&item)).ShouldShowInShelf();
282 } 249 }
283 250
284 } // namespace 251 } // namespace
285 252
286 DownloadsDOMHandler::DownloadsDOMHandler(content::DownloadManager* dlm) 253 DownloadsDOMHandler::DownloadsDOMHandler(content::DownloadManager* dlm)
287 : main_notifier_(dlm, this), 254 : main_notifier_(dlm, this),
288 update_scheduled_(false), 255 update_scheduled_(false),
289 weak_ptr_factory_(this) { 256 weak_ptr_factory_(this) {
290 // Create our fileicon data source. 257 // Create our fileicon data source.
291 Profile* profile = Profile::FromBrowserContext(dlm->GetBrowserContext()); 258 Profile* profile = Profile::FromBrowserContext(dlm->GetBrowserContext());
292 content::URLDataSource::Add(profile, new FileIconSource()); 259 content::URLDataSource::Add(profile, new FileIconSource());
293 260
294 if (profile->IsOffTheRecord()) { 261 if (profile->IsOffTheRecord()) {
295 original_notifier_.reset(new AllDownloadItemNotifier( 262 original_notifier_.reset(new AllDownloadItemNotifier(
296 BrowserContext::GetDownloadManager(profile->GetOriginalProfile()), 263 BrowserContext::GetDownloadManager(profile->GetOriginalProfile()),
297 this)); 264 this));
298 } 265 }
299 } 266 }
300 267
301 DownloadsDOMHandler::~DownloadsDOMHandler() { 268 DownloadsDOMHandler::~DownloadsDOMHandler() {
302 while (!removes_.empty()) { 269 FinalizeRemovals();
303 const std::set<uint32> remove = removes_.back();
304 removes_.pop_back();
305
306 for (const auto id : remove) {
307 content::DownloadItem* download = GetDownloadById(id);
308 if (download)
309 download->Remove();
310 }
311 }
312 } 270 }
313 271
314 // DownloadsDOMHandler, public: ----------------------------------------------- 272 // DownloadsDOMHandler, public: -----------------------------------------------
315 273
316 void DownloadsDOMHandler::OnPageLoaded(const base::ListValue* args) { 274 void DownloadsDOMHandler::OnPageLoaded(const base::ListValue* args) {
317 SendCurrentDownloads(); 275 SendCurrentDownloads();
318 } 276 }
319 277
320 void DownloadsDOMHandler::RegisterMessages() { 278 void DownloadsDOMHandler::RegisterMessages() {
321 web_ui()->RegisterMessageCallback("onPageLoaded", 279 web_ui()->RegisterMessageCallback("onPageLoaded",
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 (manager == main_notifier_.GetManager())))); 349 (manager == main_notifier_.GetManager()))));
392 CallDownloadUpdated(results_value); 350 CallDownloadUpdated(results_value);
393 } else { 351 } else {
394 ScheduleSendCurrentDownloads(); 352 ScheduleSendCurrentDownloads();
395 } 353 }
396 } 354 }
397 355
398 void DownloadsDOMHandler::OnDownloadRemoved( 356 void DownloadsDOMHandler::OnDownloadRemoved(
399 content::DownloadManager* manager, 357 content::DownloadManager* manager,
400 content::DownloadItem* download_item) { 358 content::DownloadItem* download_item) {
401 if (IsRemoved(*download_item)) 359 if (!DownloadItemModel(download_item).ShouldShowInShelf())
402 return; 360 return;
403 361
404 // This relies on |download_item| being removed from DownloadManager in this 362 // This relies on |download_item| being removed from DownloadManager in this
405 // MessageLoop iteration. |download_item| may not have been removed from 363 // MessageLoop iteration. |download_item| may not have been removed from
406 // DownloadManager when OnDownloadRemoved() is fired, so bounce off the 364 // DownloadManager when OnDownloadRemoved() is fired, so bounce off the
407 // MessageLoop to give it a chance to be removed. SendCurrentDownloads() looks 365 // MessageLoop to give it a chance to be removed. SendCurrentDownloads() looks
408 // at all downloads, and we do not tell it that |download_item| is being 366 // at all downloads, and we do not tell it that |download_item| is being
409 // removed. If DownloadManager is ever changed to not immediately remove 367 // removed. If DownloadManager is ever changed to not immediately remove
410 // |download_item| from its map when OnDownloadRemoved is sent, then 368 // |download_item| from its map when OnDownloadRemoved is sent, then
411 // DownloadsDOMHandler::OnDownloadRemoved() will need to explicitly tell 369 // DownloadsDOMHandler::OnDownloadRemoved() will need to explicitly tell
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 if (!file) 454 if (!file)
497 return; 455 return;
498 456
499 std::vector<content::DownloadItem*> downloads; 457 std::vector<content::DownloadItem*> downloads;
500 downloads.push_back(file); 458 downloads.push_back(file);
501 RemoveDownloads(downloads); 459 RemoveDownloads(downloads);
502 } 460 }
503 461
504 void DownloadsDOMHandler::HandleUndo(const base::ListValue* args) { 462 void DownloadsDOMHandler::HandleUndo(const base::ListValue* args) {
505 // TODO(dbeam): handle more than removed downloads someday? 463 // TODO(dbeam): handle more than removed downloads someday?
506 if (removes_.empty()) 464 if (removals_.empty())
507 return; 465 return;
508 466
509 const std::set<uint32> last_removed_ids = removes_.back(); 467 const std::set<uint32> last_removed_ids = removals_.back();
510 removes_.pop_back(); 468 removals_.pop_back();
511 469
512 for (auto id : last_removed_ids) { 470 for (auto id : last_removed_ids) {
513 content::DownloadItem* download = GetDownloadById(id); 471 content::DownloadItem* download = GetDownloadById(id);
514 if (!download) 472 if (!download)
515 continue; 473 continue;
516 DownloadsDOMHandlerData::Set(download, nullptr); 474 DownloadItemModel(download).SetShouldShowInShelf(true);
517 download->UpdateObservers(); 475 download->UpdateObservers();
518 } 476 }
519 } 477 }
520 478
521 void DownloadsDOMHandler::HandleCancel(const base::ListValue* args) { 479 void DownloadsDOMHandler::HandleCancel(const base::ListValue* args) {
522 CountDownloadsDOMEvents(DOWNLOADS_DOM_EVENT_CANCEL); 480 CountDownloadsDOMEvents(DOWNLOADS_DOM_EVENT_CANCEL);
523 content::DownloadItem* file = GetDownloadByValue(args); 481 content::DownloadItem* file = GetDownloadByValue(args);
524 if (file) 482 if (file)
525 file->Cancel(true); 483 file->Cancel(true);
526 } 484 }
527 485
528 void DownloadsDOMHandler::HandleClearAll(const base::ListValue* args) { 486 void DownloadsDOMHandler::HandleClearAll(const base::ListValue* args) {
529 if (!IsDeletingHistoryAllowed()) 487 if (!IsDeletingHistoryAllowed())
530 return; 488 return;
531 489
532 CountDownloadsDOMEvents(DOWNLOADS_DOM_EVENT_CLEAR_ALL); 490 CountDownloadsDOMEvents(DOWNLOADS_DOM_EVENT_CLEAR_ALL);
533 491
534 std::vector<content::DownloadItem*> downloads; 492 std::vector<content::DownloadItem*> downloads;
535 if (GetMainNotifierManager()) 493 if (GetMainNotifierManager())
536 GetMainNotifierManager()->GetAllDownloads(&downloads); 494 GetMainNotifierManager()->GetAllDownloads(&downloads);
537 if (original_notifier_ && original_notifier_->GetManager()) 495 if (original_notifier_ && original_notifier_->GetManager())
538 original_notifier_->GetManager()->GetAllDownloads(&downloads); 496 original_notifier_->GetManager()->GetAllDownloads(&downloads);
539 RemoveDownloads(downloads); 497 RemoveDownloads(downloads);
540 } 498 }
541 499
542 void DownloadsDOMHandler::RemoveDownloads( 500 void DownloadsDOMHandler::RemoveDownloads(
543 const std::vector<content::DownloadItem*>& to_remove) { 501 const std::vector<content::DownloadItem*>& to_remove) {
544 std::set<uint32> ids; 502 std::set<uint32> ids;
545 for (auto* download : to_remove) { 503 for (auto* download : to_remove) {
546 if (IsRemoved(*download) || 504 DownloadItemModel item_model(download);
505 if (!item_model.ShouldShowInShelf() ||
547 download->GetState() == content::DownloadItem::IN_PROGRESS) { 506 download->GetState() == content::DownloadItem::IN_PROGRESS) {
548 continue; 507 continue;
549 } 508 }
550 509
551 DownloadsDOMHandlerData::Create(download)->set_is_removed(true); 510 item_model.SetShouldShowInShelf(false);
552 ids.insert(download->GetId()); 511 ids.insert(download->GetId());
553 download->UpdateObservers(); 512 download->UpdateObservers();
554 } 513 }
555 removes_.push_back(ids); 514 if (!ids.empty())
515 removals_.push_back(ids);
556 } 516 }
557 517
558 void DownloadsDOMHandler::HandleOpenDownloadsFolder( 518 void DownloadsDOMHandler::HandleOpenDownloadsFolder(
559 const base::ListValue* args) { 519 const base::ListValue* args) {
560 CountDownloadsDOMEvents(DOWNLOADS_DOM_EVENT_OPEN_FOLDER); 520 CountDownloadsDOMEvents(DOWNLOADS_DOM_EVENT_OPEN_FOLDER);
561 content::DownloadManager* manager = main_notifier_.GetManager(); 521 content::DownloadManager* manager = main_notifier_.GetManager();
562 if (manager) { 522 if (manager) {
563 platform_util::OpenItem( 523 platform_util::OpenItem(
564 Profile::FromBrowserContext(manager->GetBrowserContext()), 524 Profile::FromBrowserContext(manager->GetBrowserContext()),
565 DownloadPrefs::FromDownloadManager(manager)->DownloadPath()); 525 DownloadPrefs::FromDownloadManager(manager)->DownloadPath());
(...skipping 12 matching lines...) Expand all
578 BrowserThread::PostTask( 538 BrowserThread::PostTask(
579 BrowserThread::UI, FROM_HERE, 539 BrowserThread::UI, FROM_HERE,
580 base::Bind(&DownloadsDOMHandler::SendCurrentDownloads, 540 base::Bind(&DownloadsDOMHandler::SendCurrentDownloads,
581 weak_ptr_factory_.GetWeakPtr())); 541 weak_ptr_factory_.GetWeakPtr()));
582 } 542 }
583 543
584 content::DownloadManager* DownloadsDOMHandler::GetMainNotifierManager() { 544 content::DownloadManager* DownloadsDOMHandler::GetMainNotifierManager() {
585 return main_notifier_.GetManager(); 545 return main_notifier_.GetManager();
586 } 546 }
587 547
548 void DownloadsDOMHandler::FinalizeRemovals() {
549 while (!removals_.empty()) {
550 const std::set<uint32> remove = removals_.back();
551 removals_.pop_back();
552
553 for (const auto id : remove) {
554 content::DownloadItem* download = GetDownloadById(id);
555 if (download)
556 download->Remove();
557 }
558 }
559 }
560
588 void DownloadsDOMHandler::SendCurrentDownloads() { 561 void DownloadsDOMHandler::SendCurrentDownloads() {
589 update_scheduled_ = false; 562 update_scheduled_ = false;
590 content::DownloadManager::DownloadVector all_items, filtered_items; 563 content::DownloadManager::DownloadVector all_items, filtered_items;
591 if (main_notifier_.GetManager()) { 564 if (main_notifier_.GetManager()) {
592 main_notifier_.GetManager()->GetAllDownloads(&all_items); 565 main_notifier_.GetManager()->GetAllDownloads(&all_items);
593 main_notifier_.GetManager()->CheckForHistoryFilesRemoval(); 566 main_notifier_.GetManager()->CheckForHistoryFilesRemoval();
594 } 567 }
595 if (original_notifier_.get() && original_notifier_->GetManager()) { 568 if (original_notifier_.get() && original_notifier_->GetManager()) {
596 original_notifier_->GetManager()->GetAllDownloads(&all_items); 569 original_notifier_->GetManager()->GetAllDownloads(&all_items);
597 original_notifier_->GetManager()->CheckForHistoryFilesRemoval(); 570 original_notifier_->GetManager()->CheckForHistoryFilesRemoval();
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 if (!base::StringToUint64(download_id, &id)) { 636 if (!base::StringToUint64(download_id, &id)) {
664 NOTREACHED(); 637 NOTREACHED();
665 return nullptr; 638 return nullptr;
666 } 639 }
667 640
668 return GetDownloadById(static_cast<uint32>(id)); 641 return GetDownloadById(static_cast<uint32>(id));
669 } 642 }
670 643
671 content::DownloadItem* DownloadsDOMHandler::GetDownloadById(uint32 id) { 644 content::DownloadItem* DownloadsDOMHandler::GetDownloadById(uint32 id) {
672 content::DownloadItem* item = NULL; 645 content::DownloadItem* item = NULL;
673 if (main_notifier_.GetManager()) 646 if (GetMainNotifierManager())
674 item = main_notifier_.GetManager()->GetDownload(id); 647 item = GetMainNotifierManager()->GetDownload(id);
675 if (!item && original_notifier_.get() && original_notifier_->GetManager()) 648 if (!item && original_notifier_.get() && original_notifier_->GetManager())
676 item = original_notifier_->GetManager()->GetDownload(id); 649 item = original_notifier_->GetManager()->GetDownload(id);
677 return item; 650 return item;
678 } 651 }
679 652
680 content::WebContents* DownloadsDOMHandler::GetWebUIWebContents() { 653 content::WebContents* DownloadsDOMHandler::GetWebUIWebContents() {
681 return web_ui()->GetWebContents(); 654 return web_ui()->GetWebContents();
682 } 655 }
683 656
684 void DownloadsDOMHandler::CallDownloadsList(const base::ListValue& downloads) { 657 void DownloadsDOMHandler::CallDownloadsList(const base::ListValue& downloads) {
685 web_ui()->CallJavascriptFunction("downloadsList", downloads); 658 web_ui()->CallJavascriptFunction("downloadsList", downloads);
686 } 659 }
687 660
688 void DownloadsDOMHandler::CallDownloadUpdated( 661 void DownloadsDOMHandler::CallDownloadUpdated(
689 const base::ListValue& download_item) { 662 const base::ListValue& download_item) {
690 web_ui()->CallJavascriptFunction("downloadUpdated", download_item); 663 web_ui()->CallJavascriptFunction("downloadUpdated", download_item);
691 } 664 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/webui/downloads_dom_handler.h ('k') | chrome/browser/ui/webui/downloads_dom_handler_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698