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

Side by Side Diff: chrome/browser/ui/webui/md_downloads/downloads_list_tracker.cc

Issue 1492273002: MD Downloads: limit the amount of downloads we send (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@new-dl-data
Patch Set: self-review Created 5 years 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/md_downloads/downloads_list_tracker.h" 5 #include "chrome/browser/ui/webui/md_downloads/downloads_list_tracker.h"
6 6
7 #include <iterator> 7 #include <iterator>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
(...skipping 20 matching lines...) Expand all
31 #include "ui/base/l10n/time_format.h" 31 #include "ui/base/l10n/time_format.h"
32 32
33 using content::BrowserContext; 33 using content::BrowserContext;
34 using content::DownloadItem; 34 using content::DownloadItem;
35 using content::DownloadManager; 35 using content::DownloadManager;
36 36
37 using DownloadVector = DownloadManager::DownloadVector; 37 using DownloadVector = DownloadManager::DownloadVector;
38 38
39 namespace { 39 namespace {
40 40
41 const size_t kChunkSize = 20u;
42
41 // Returns a string constant to be used as the |danger_type| value in 43 // Returns a string constant to be used as the |danger_type| value in
42 // CreateDownloadItemValue(). Only return strings for DANGEROUS_FILE, 44 // CreateDownloadItemValue(). Only return strings for DANGEROUS_FILE,
43 // DANGEROUS_URL, DANGEROUS_CONTENT, and UNCOMMON_CONTENT because the 45 // DANGEROUS_URL, DANGEROUS_CONTENT, and UNCOMMON_CONTENT because the
44 // |danger_type| value is only defined if the value of |state| is |DANGEROUS|. 46 // |danger_type| value is only defined if the value of |state| is |DANGEROUS|.
45 const char* GetDangerTypeString(content::DownloadDangerType danger_type) { 47 const char* GetDangerTypeString(content::DownloadDangerType danger_type) {
46 switch (danger_type) { 48 switch (danger_type) {
47 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE: 49 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE:
48 return "DANGEROUS_FILE"; 50 return "DANGEROUS_FILE";
49 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL: 51 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL:
50 return "DANGEROUS_URL"; 52 return "DANGEROUS_URL";
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 content::WebUI* web_ui) 87 content::WebUI* web_ui)
86 : main_notifier_(download_manager, this), 88 : main_notifier_(download_manager, this),
87 web_ui_(web_ui), 89 web_ui_(web_ui),
88 should_show_(base::Bind(&DownloadsListTracker::ShouldShow, 90 should_show_(base::Bind(&DownloadsListTracker::ShouldShow,
89 base::Unretained(this))) { 91 base::Unretained(this))) {
90 Init(); 92 Init();
91 } 93 }
92 94
93 DownloadsListTracker::~DownloadsListTracker() {} 95 DownloadsListTracker::~DownloadsListTracker() {}
94 96
95 void DownloadsListTracker::CallClearAll() {
96 if (sending_updates_)
97 web_ui_->CallJavascriptFunction("downloads.Manager.clearAll");
98 }
99
100 bool DownloadsListTracker::SetSearchTerms(const base::ListValue& search_terms) { 97 bool DownloadsListTracker::SetSearchTerms(const base::ListValue& search_terms) {
101 std::vector<base::string16> new_terms; 98 std::vector<base::string16> new_terms;
102 new_terms.resize(search_terms.GetSize()); 99 new_terms.resize(search_terms.GetSize());
103 100
104 for (size_t i = 0; i < search_terms.GetSize(); ++i) 101 for (size_t i = 0; i < search_terms.GetSize(); ++i)
105 search_terms.GetString(i, &new_terms[i]); 102 search_terms.GetString(i, &new_terms[i]);
106 103
107 if (new_terms == search_terms_) 104 if (new_terms == search_terms_)
108 return false; 105 return false;
109 106
110 search_terms_.swap(new_terms); 107 search_terms_.swap(new_terms);
111 RebuildSortedSet(); 108 RebuildSortedItems();
112 return true; 109 return true;
113 } 110 }
114 111
115 void DownloadsListTracker::Start() { 112 void DownloadsListTracker::StartAndSendChunk() {
116 sending_updates_ = true; 113 sending_updates_ = true;
117 114
118 // TODO(dbeam): paging and limiting logic. 115 CHECK_LE(sent_to_page_, sorted_items_.size());
116
117 SortedSet::iterator it = sorted_items_.begin();
118 std::advance(it, sent_to_page_);
119 119
120 base::ListValue list; 120 base::ListValue list;
121 for (auto* item : sorted_visible_items_) 121 while (it != sorted_items_.end() && list.GetSize() < kChunkSize) {
122 list.Append(CreateDownloadItemValue(item).Pass()); 122 list.Append(CreateDownloadItemValue(*it).Pass());
123 ++it;
124 }
123 125
124 web_ui_->CallJavascriptFunction("downloads.Manager.insertItems", 126 web_ui_->CallJavascriptFunction(
125 base::FundamentalValue(0), list); 127 "downloads.Manager.insertItems",
128 base::FundamentalValue(static_cast<int>(sent_to_page_)),
129 list);
130
131 sent_to_page_ += list.GetSize();
126 } 132 }
127 133
128 void DownloadsListTracker::Stop() { 134 void DownloadsListTracker::Reset() {
135 if (sending_updates_)
136 web_ui_->CallJavascriptFunction("downloads.Manager.clearAll");
137
129 sending_updates_ = false; 138 sending_updates_ = false;
139 sent_to_page_ = 0u;
130 } 140 }
131 141
132 DownloadManager* DownloadsListTracker::GetMainNotifierManager() const { 142 DownloadManager* DownloadsListTracker::GetMainNotifierManager() const {
133 return main_notifier_.GetManager(); 143 return main_notifier_.GetManager();
134 } 144 }
135 145
136 DownloadManager* DownloadsListTracker::GetOriginalNotifierManager() const { 146 DownloadManager* DownloadsListTracker::GetOriginalNotifierManager() const {
137 return original_notifier_ ? original_notifier_->GetManager() : nullptr; 147 return original_notifier_ ? original_notifier_->GetManager() : nullptr;
138 } 148 }
139 149
140 void DownloadsListTracker::OnDownloadCreated(DownloadManager* manager, 150 void DownloadsListTracker::OnDownloadCreated(DownloadManager* manager,
141 DownloadItem* download_item) { 151 DownloadItem* download_item) {
152 DCHECK_EQ(0u, sorted_items_.count(download_item));
142 if (should_show_.Run(*download_item)) 153 if (should_show_.Run(*download_item))
143 CallInsertItem(sorted_visible_items_.insert(download_item).first); 154 InsertItem(sorted_items_.insert(download_item).first);
144 } 155 }
145 156
146 void DownloadsListTracker::OnDownloadUpdated(DownloadManager* manager, 157 void DownloadsListTracker::OnDownloadUpdated(DownloadManager* manager,
147 DownloadItem* download_item) { 158 DownloadItem* download_item) {
148 auto current_position = sorted_visible_items_.find(download_item); 159 auto current_position = sorted_items_.find(download_item);
149 bool is_showing = current_position != sorted_visible_items_.end(); 160 bool is_showing = current_position != sorted_items_.end();
150 bool should_show = should_show_.Run(*download_item); 161 bool should_show = should_show_.Run(*download_item);
151 162
152 if (!is_showing && should_show) 163 if (!is_showing && should_show)
153 CallInsertItem(sorted_visible_items_.insert(download_item).first); 164 InsertItem(sorted_items_.insert(download_item).first);
154 else if (is_showing && !should_show) 165 else if (is_showing && !should_show)
155 RemoveItem(current_position); 166 RemoveItem(current_position);
156 else if (is_showing) 167 else if (is_showing)
157 CallUpdateItem(current_position); 168 UpdateItem(current_position);
158 } 169 }
159 170
160 void DownloadsListTracker::OnDownloadRemoved(DownloadManager* manager, 171 void DownloadsListTracker::OnDownloadRemoved(DownloadManager* manager,
161 DownloadItem* download_item) { 172 DownloadItem* download_item) {
162 auto current_position = sorted_visible_items_.find(download_item); 173 auto current_position = sorted_items_.find(download_item);
163 if (current_position != sorted_visible_items_.end()) 174 if (current_position != sorted_items_.end())
164 RemoveItem(current_position); 175 RemoveItem(current_position);
165 } 176 }
166 177
167 DownloadsListTracker::DownloadsListTracker( 178 DownloadsListTracker::DownloadsListTracker(
168 DownloadManager* download_manager, 179 DownloadManager* download_manager,
169 content::WebUI* web_ui, 180 content::WebUI* web_ui,
170 base::Callback<bool(const DownloadItem&)> should_show) 181 base::Callback<bool(const DownloadItem&)> should_show)
171 : main_notifier_(download_manager, this), 182 : main_notifier_(download_manager, this),
172 web_ui_(web_ui), 183 web_ui_(web_ui),
173 should_show_(should_show) { 184 should_show_(should_show) {
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 file_value->SetInteger("percent", percent); 313 file_value->SetInteger("percent", percent);
303 file_value->SetString("progress_status_text", progress_status_text); 314 file_value->SetString("progress_status_text", progress_status_text);
304 file_value->SetBoolean("retry", retry); 315 file_value->SetBoolean("retry", retry);
305 file_value->SetString("state", state); 316 file_value->SetString("state", state);
306 317
307 return file_value.Pass(); 318 return file_value.Pass();
308 } 319 }
309 320
310 const DownloadItem* DownloadsListTracker::GetItemForTesting(size_t index) 321 const DownloadItem* DownloadsListTracker::GetItemForTesting(size_t index)
311 const { 322 const {
312 if (index >= sorted_visible_items_.size()) 323 if (index >= sorted_items_.size())
313 return nullptr; 324 return nullptr;
314 325
315 SortedSet::iterator it = sorted_visible_items_.begin(); 326 SortedSet::iterator it = sorted_items_.begin();
316 std::advance(it, index); 327 std::advance(it, index);
317 return *it; 328 return *it;
318 } 329 }
319 330
320 bool DownloadsListTracker::ShouldShow(const DownloadItem& item) const { 331 bool DownloadsListTracker::ShouldShow(const DownloadItem& item) const {
321 return !download_crx_util::IsExtensionDownload(item) && 332 return !download_crx_util::IsExtensionDownload(item) &&
322 !item.IsTemporary() && 333 !item.IsTemporary() &&
323 !item.GetFileNameToReportUser().empty() && 334 !item.GetFileNameToReportUser().empty() &&
324 !item.GetTargetFilePath().empty() && 335 !item.GetTargetFilePath().empty() &&
325 DownloadItemModel(const_cast<DownloadItem*>(&item)).ShouldShowInShelf() && 336 DownloadItemModel(const_cast<DownloadItem*>(&item)).ShouldShowInShelf() &&
326 DownloadQuery::MatchesQuery(search_terms_, item); 337 DownloadQuery::MatchesQuery(search_terms_, item);
327 } 338 }
328 339
329 bool DownloadsListTracker::StartTimeComparator::operator() ( 340 bool DownloadsListTracker::StartTimeComparator::operator() (
330 const content::DownloadItem* a, const content::DownloadItem* b) const { 341 const content::DownloadItem* a, const content::DownloadItem* b) const {
331 return a->GetStartTime() > b->GetStartTime(); 342 return a->GetStartTime() > b->GetStartTime();
332 } 343 }
333 344
334 void DownloadsListTracker::Init() { 345 void DownloadsListTracker::Init() {
335 Profile* profile = Profile::FromBrowserContext( 346 Profile* profile = Profile::FromBrowserContext(
336 GetMainNotifierManager()->GetBrowserContext()); 347 GetMainNotifierManager()->GetBrowserContext());
337 if (profile->IsOffTheRecord()) { 348 if (profile->IsOffTheRecord()) {
338 original_notifier_.reset(new AllDownloadItemNotifier( 349 original_notifier_.reset(new AllDownloadItemNotifier(
339 BrowserContext::GetDownloadManager(profile->GetOriginalProfile()), 350 BrowserContext::GetDownloadManager(profile->GetOriginalProfile()),
340 this)); 351 this));
341 } 352 }
342 353
343 RebuildSortedSet(); 354 RebuildSortedItems();
344 } 355 }
345 356
346 void DownloadsListTracker::RebuildSortedSet() { 357 void DownloadsListTracker::RebuildSortedItems() {
347 DownloadVector all_items, visible_items; 358 DownloadVector all_items, visible_items;
348 359
349 GetMainNotifierManager()->GetAllDownloads(&all_items); 360 GetMainNotifierManager()->GetAllDownloads(&all_items);
350 361
351 if (GetOriginalNotifierManager()) 362 if (GetOriginalNotifierManager())
352 GetOriginalNotifierManager()->GetAllDownloads(&all_items); 363 GetOriginalNotifierManager()->GetAllDownloads(&all_items);
353 364
354 DownloadQuery query; 365 DownloadQuery query;
355 query.AddFilter(should_show_); 366 query.AddFilter(should_show_);
356 query.Search(all_items.begin(), all_items.end(), &visible_items); 367 query.Search(all_items.begin(), all_items.end(), &visible_items);
357 368
358 SortedSet sorted_visible_items(visible_items.begin(), visible_items.end()); 369 SortedSet sorted_items(visible_items.begin(), visible_items.end());
359 sorted_visible_items_.swap(sorted_visible_items); 370 sorted_items_.swap(sorted_items);
360 } 371 }
361 372
362 void DownloadsListTracker::CallInsertItem(const SortedSet::iterator& insert) { 373 void DownloadsListTracker::InsertItem(const SortedSet::iterator& insert) {
363 if (!sending_updates_) 374 if (!sending_updates_)
364 return; 375 return;
365 376
377 size_t index = GetIndex(insert);
378 if (index > kChunkSize && index >= sent_to_page_)
asanka 2015/12/04 21:03:56 What's the point of the (index > kChunkSize)? Don'
Dan Beam 2015/12/04 22:52:35 when the first download ever is created, sent_to_p
Dan Beam 2015/12/05 00:31:43 and if you were wondering how we avoid pathologica
asanka 2015/12/07 20:31:50 Ok. My misunderstanding was that I thought this co
Dan Beam 2015/12/09 06:55:21 the only way users currently know if there are mor
379 return;
380
366 base::ListValue list; 381 base::ListValue list;
367 list.Append(CreateDownloadItemValue(*insert).Pass()); 382 list.Append(CreateDownloadItemValue(*insert).Pass());
368 383
369 web_ui_->CallJavascriptFunction("downloads.Manager.insertItems", 384 web_ui_->CallJavascriptFunction(
370 base::FundamentalValue(GetIndex(insert)), 385 "downloads.Manager.insertItems",
371 list); 386 base::FundamentalValue(static_cast<int>(index)),
387 list);
388
389 sent_to_page_++;
372 } 390 }
373 391
374 void DownloadsListTracker::CallUpdateItem(const SortedSet::iterator& update) { 392 void DownloadsListTracker::UpdateItem(const SortedSet::iterator& update) {
375 if (!sending_updates_) 393 if (!sending_updates_ || GetIndex(update) >= sent_to_page_)
376 return; 394 return;
377 395
378 web_ui_->CallJavascriptFunction("downloads.Manager.updateItem", 396 web_ui_->CallJavascriptFunction(
379 base::FundamentalValue(GetIndex(update)), 397 "downloads.Manager.updateItem",
380 *CreateDownloadItemValue(*update)); 398 base::FundamentalValue(static_cast<int>(GetIndex(update))),
399 *CreateDownloadItemValue(*update));
381 } 400 }
382 401
383 int DownloadsListTracker::GetIndex(const SortedSet::iterator& position) const { 402 size_t DownloadsListTracker::GetIndex(const SortedSet::iterator& item) const {
384 // TODO(dbeam): this could be log(N) if |position| was random access. 403 // TODO(dbeam): this could be log(N) if |item| was random access.
385 return std::distance(sorted_visible_items_.begin(), position); 404 return std::distance(sorted_items_.begin(), item);
386 } 405 }
387 406
388 void DownloadsListTracker::RemoveItem(const SortedSet::iterator& remove) { 407 void DownloadsListTracker::RemoveItem(const SortedSet::iterator& remove) {
389 if (sending_updates_) { 408 if (sending_updates_) {
390 web_ui_->CallJavascriptFunction("downloads.Manager.removeItem", 409 size_t index = GetIndex(remove);
391 base::FundamentalValue(GetIndex(remove))); 410 if (index < sent_to_page_) {
411 web_ui_->CallJavascriptFunction(
412 "downloads.Manager.removeItem",
413 base::FundamentalValue(static_cast<int>(index)));
414 sent_to_page_--;
415 }
392 } 416 }
393 sorted_visible_items_.erase(remove); 417 sorted_items_.erase(remove);
394 } 418 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698