OLD | NEW |
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 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 content::WebUI* web_ui) | 85 content::WebUI* web_ui) |
86 : main_notifier_(download_manager, this), | 86 : main_notifier_(download_manager, this), |
87 web_ui_(web_ui), | 87 web_ui_(web_ui), |
88 should_show_(base::Bind(&DownloadsListTracker::ShouldShow, | 88 should_show_(base::Bind(&DownloadsListTracker::ShouldShow, |
89 base::Unretained(this))) { | 89 base::Unretained(this))) { |
90 Init(); | 90 Init(); |
91 } | 91 } |
92 | 92 |
93 DownloadsListTracker::~DownloadsListTracker() {} | 93 DownloadsListTracker::~DownloadsListTracker() {} |
94 | 94 |
95 void DownloadsListTracker::CallClearAll() { | 95 void DownloadsListTracker::Reset() { |
96 if (sending_updates_) | 96 if (sending_updates_) |
97 web_ui_->CallJavascriptFunction("downloads.Manager.clearAll"); | 97 web_ui_->CallJavascriptFunction("downloads.Manager.clearAll"); |
| 98 sent_to_page_ = 0u; |
98 } | 99 } |
99 | 100 |
100 bool DownloadsListTracker::SetSearchTerms(const base::ListValue& search_terms) { | 101 bool DownloadsListTracker::SetSearchTerms(const base::ListValue& search_terms) { |
101 std::vector<base::string16> new_terms; | 102 std::vector<base::string16> new_terms; |
102 new_terms.resize(search_terms.GetSize()); | 103 new_terms.resize(search_terms.GetSize()); |
103 | 104 |
104 for (size_t i = 0; i < search_terms.GetSize(); ++i) | 105 for (size_t i = 0; i < search_terms.GetSize(); ++i) |
105 search_terms.GetString(i, &new_terms[i]); | 106 search_terms.GetString(i, &new_terms[i]); |
106 | 107 |
107 if (new_terms == search_terms_) | 108 if (new_terms == search_terms_) |
108 return false; | 109 return false; |
109 | 110 |
110 search_terms_.swap(new_terms); | 111 search_terms_.swap(new_terms); |
111 RebuildSortedSet(); | 112 RebuildSortedItems(); |
112 return true; | 113 return true; |
113 } | 114 } |
114 | 115 |
115 void DownloadsListTracker::Start() { | 116 void DownloadsListTracker::StartAndSendChunk() { |
116 sending_updates_ = true; | 117 sending_updates_ = true; |
117 | 118 |
118 // TODO(dbeam): paging and limiting logic. | 119 CHECK_LE(sent_to_page_, sorted_items_.size()); |
| 120 |
| 121 SortedSet::iterator it = sorted_items_.begin(); |
| 122 std::advance(it, sent_to_page_); |
119 | 123 |
120 base::ListValue list; | 124 base::ListValue list; |
121 for (auto* item : sorted_visible_items_) | 125 while (it != sorted_items_.end() && list.GetSize() < chunk_size_) { |
122 list.Append(CreateDownloadItemValue(item).Pass()); | 126 list.Append(CreateDownloadItemValue(*it).Pass()); |
| 127 ++it; |
| 128 } |
123 | 129 |
124 web_ui_->CallJavascriptFunction("downloads.Manager.insertItems", | 130 web_ui_->CallJavascriptFunction( |
125 base::FundamentalValue(0), list); | 131 "downloads.Manager.insertItems", |
| 132 base::FundamentalValue(static_cast<int>(sent_to_page_)), |
| 133 list); |
| 134 |
| 135 sent_to_page_ += list.GetSize(); |
126 } | 136 } |
127 | 137 |
128 void DownloadsListTracker::Stop() { | 138 void DownloadsListTracker::Stop() { |
129 sending_updates_ = false; | 139 sending_updates_ = false; |
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 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
300 return file_value.Pass(); | 311 return file_value.Pass(); |
301 } | 312 } |
302 | 313 |
303 bool DownloadsListTracker::IsIncognito(const DownloadItem& item) const { | 314 bool DownloadsListTracker::IsIncognito(const DownloadItem& item) const { |
304 return GetOriginalNotifierManager() && GetMainNotifierManager() && | 315 return GetOriginalNotifierManager() && GetMainNotifierManager() && |
305 GetMainNotifierManager()->GetDownload(item.GetId()) == &item; | 316 GetMainNotifierManager()->GetDownload(item.GetId()) == &item; |
306 } | 317 } |
307 | 318 |
308 const DownloadItem* DownloadsListTracker::GetItemForTesting(size_t index) | 319 const DownloadItem* DownloadsListTracker::GetItemForTesting(size_t index) |
309 const { | 320 const { |
310 if (index >= sorted_visible_items_.size()) | 321 if (index >= sorted_items_.size()) |
311 return nullptr; | 322 return nullptr; |
312 | 323 |
313 SortedSet::iterator it = sorted_visible_items_.begin(); | 324 SortedSet::iterator it = sorted_items_.begin(); |
314 std::advance(it, index); | 325 std::advance(it, index); |
315 return *it; | 326 return *it; |
316 } | 327 } |
317 | 328 |
| 329 void DownloadsListTracker::SetChunkSizeForTesting(size_t chunk_size) { |
| 330 CHECK_EQ(0u, sent_to_page_); |
| 331 chunk_size_ = chunk_size; |
| 332 } |
| 333 |
318 bool DownloadsListTracker::ShouldShow(const DownloadItem& item) const { | 334 bool DownloadsListTracker::ShouldShow(const DownloadItem& item) const { |
319 return !download_crx_util::IsExtensionDownload(item) && | 335 return !download_crx_util::IsExtensionDownload(item) && |
320 !item.IsTemporary() && | 336 !item.IsTemporary() && |
321 !item.GetFileNameToReportUser().empty() && | 337 !item.GetFileNameToReportUser().empty() && |
322 !item.GetTargetFilePath().empty() && | 338 !item.GetTargetFilePath().empty() && |
323 DownloadItemModel(const_cast<DownloadItem*>(&item)).ShouldShowInShelf() && | 339 DownloadItemModel(const_cast<DownloadItem*>(&item)).ShouldShowInShelf() && |
324 DownloadQuery::MatchesQuery(search_terms_, item); | 340 DownloadQuery::MatchesQuery(search_terms_, item); |
325 } | 341 } |
326 | 342 |
327 bool DownloadsListTracker::StartTimeComparator::operator() ( | 343 bool DownloadsListTracker::StartTimeComparator::operator() ( |
328 const content::DownloadItem* a, const content::DownloadItem* b) const { | 344 const content::DownloadItem* a, const content::DownloadItem* b) const { |
329 return a->GetStartTime() > b->GetStartTime(); | 345 return a->GetStartTime() > b->GetStartTime(); |
330 } | 346 } |
331 | 347 |
332 void DownloadsListTracker::Init() { | 348 void DownloadsListTracker::Init() { |
333 Profile* profile = Profile::FromBrowserContext( | 349 Profile* profile = Profile::FromBrowserContext( |
334 GetMainNotifierManager()->GetBrowserContext()); | 350 GetMainNotifierManager()->GetBrowserContext()); |
335 if (profile->IsOffTheRecord()) { | 351 if (profile->IsOffTheRecord()) { |
336 Profile* original_profile = profile->GetOriginalProfile(); | 352 Profile* original_profile = profile->GetOriginalProfile(); |
337 original_notifier_.reset(new AllDownloadItemNotifier( | 353 original_notifier_.reset(new AllDownloadItemNotifier( |
338 BrowserContext::GetDownloadManager(original_profile), this)); | 354 BrowserContext::GetDownloadManager(original_profile), this)); |
339 } | 355 } |
340 | 356 |
341 RebuildSortedSet(); | 357 RebuildSortedItems(); |
342 } | 358 } |
343 | 359 |
344 void DownloadsListTracker::RebuildSortedSet() { | 360 void DownloadsListTracker::RebuildSortedItems() { |
345 DownloadVector all_items, visible_items; | 361 DownloadVector all_items, visible_items; |
346 | 362 |
347 GetMainNotifierManager()->GetAllDownloads(&all_items); | 363 GetMainNotifierManager()->GetAllDownloads(&all_items); |
348 | 364 |
349 if (GetOriginalNotifierManager()) | 365 if (GetOriginalNotifierManager()) |
350 GetOriginalNotifierManager()->GetAllDownloads(&all_items); | 366 GetOriginalNotifierManager()->GetAllDownloads(&all_items); |
351 | 367 |
352 DownloadQuery query; | 368 DownloadQuery query; |
353 query.AddFilter(should_show_); | 369 query.AddFilter(should_show_); |
354 query.Search(all_items.begin(), all_items.end(), &visible_items); | 370 query.Search(all_items.begin(), all_items.end(), &visible_items); |
355 | 371 |
356 SortedSet sorted_visible_items(visible_items.begin(), visible_items.end()); | 372 SortedSet sorted_items(visible_items.begin(), visible_items.end()); |
357 sorted_visible_items_.swap(sorted_visible_items); | 373 sorted_items_.swap(sorted_items); |
358 } | 374 } |
359 | 375 |
360 void DownloadsListTracker::CallInsertItem(const SortedSet::iterator& insert) { | 376 void DownloadsListTracker::InsertItem(const SortedSet::iterator& insert) { |
361 if (!sending_updates_) | 377 if (!sending_updates_) |
362 return; | 378 return; |
363 | 379 |
| 380 size_t index = GetIndex(insert); |
| 381 if (index >= chunk_size_ && index >= sent_to_page_) |
| 382 return; |
| 383 |
364 base::ListValue list; | 384 base::ListValue list; |
365 list.Append(CreateDownloadItemValue(*insert).Pass()); | 385 list.Append(CreateDownloadItemValue(*insert).Pass()); |
366 | 386 |
367 web_ui_->CallJavascriptFunction("downloads.Manager.insertItems", | 387 web_ui_->CallJavascriptFunction( |
368 base::FundamentalValue(GetIndex(insert)), | 388 "downloads.Manager.insertItems", |
369 list); | 389 base::FundamentalValue(static_cast<int>(index)), |
| 390 list); |
| 391 |
| 392 sent_to_page_++; |
370 } | 393 } |
371 | 394 |
372 void DownloadsListTracker::CallUpdateItem(const SortedSet::iterator& update) { | 395 void DownloadsListTracker::UpdateItem(const SortedSet::iterator& update) { |
373 if (!sending_updates_) | 396 if (!sending_updates_ || GetIndex(update) >= sent_to_page_) |
374 return; | 397 return; |
375 | 398 |
376 web_ui_->CallJavascriptFunction("downloads.Manager.updateItem", | 399 web_ui_->CallJavascriptFunction( |
377 base::FundamentalValue(GetIndex(update)), | 400 "downloads.Manager.updateItem", |
378 *CreateDownloadItemValue(*update)); | 401 base::FundamentalValue(static_cast<int>(GetIndex(update))), |
| 402 *CreateDownloadItemValue(*update)); |
379 } | 403 } |
380 | 404 |
381 int DownloadsListTracker::GetIndex(const SortedSet::iterator& position) const { | 405 size_t DownloadsListTracker::GetIndex(const SortedSet::iterator& item) const { |
382 // TODO(dbeam): this could be log(N) if |position| was random access. | 406 // TODO(dbeam): this could be log(N) if |item| was random access. |
383 return std::distance(sorted_visible_items_.begin(), position); | 407 return std::distance(sorted_items_.begin(), item); |
384 } | 408 } |
385 | 409 |
386 void DownloadsListTracker::RemoveItem(const SortedSet::iterator& remove) { | 410 void DownloadsListTracker::RemoveItem(const SortedSet::iterator& remove) { |
387 if (sending_updates_) { | 411 if (sending_updates_) { |
388 web_ui_->CallJavascriptFunction("downloads.Manager.removeItem", | 412 size_t index = GetIndex(remove); |
389 base::FundamentalValue(GetIndex(remove))); | 413 if (index < sent_to_page_) { |
| 414 web_ui_->CallJavascriptFunction( |
| 415 "downloads.Manager.removeItem", |
| 416 base::FundamentalValue(static_cast<int>(index))); |
| 417 sent_to_page_--; |
| 418 } |
390 } | 419 } |
391 sorted_visible_items_.erase(remove); | 420 sorted_items_.erase(remove); |
392 } | 421 } |
OLD | NEW |