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 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_UI_WEBUI_DOWNLOADS_DOWNLOADS_LIST_TRACKER_H_ 6 #define CHROME_BROWSER_UI_WEBUI_DOWNLOADS_DOWNLOADS_LIST_TRACKER_H_ 7 8 #include <stddef.h> 9 10 #include <memory> 11 #include <set> 12 13 #include "base/callback_forward.h" 14 #include "base/macros.h" 15 #include "base/strings/string16.h" 16 #include "base/time/time.h" 17 #include "base/values.h" 18 #include "chrome/browser/ui/webui/downloads/downloads.mojom.h" 19 #include "components/download/content/public/all_download_item_notifier.h" 20 #include "components/download/public/common/download_item.h" 21 #include "mojo/public/cpp/bindings/pending_remote.h" 22 #include "mojo/public/cpp/bindings/remote.h" 23 24 namespace content { 25 class DownloadManager; 26 } 27 28 // A class that tracks all downloads activity and keeps a sorted representation 29 // of the downloads as chrome://downloads wants to display them. 30 class DownloadsListTracker 31 : public download::AllDownloadItemNotifier::Observer { 32 public: 33 DownloadsListTracker(content::DownloadManager* download_manager, 34 mojo::PendingRemote<downloads::mojom::Page> page); 35 ~DownloadsListTracker() override; 36 37 // Clears all downloads on the page if currently sending updates and resets 38 // chunk tracking data. 39 void Reset(); 40 41 // This class only cares about downloads that match |search_terms|. 42 // An empty list shows all downloads (the default). Returns true if 43 // |search_terms| differ from the current ones. 44 bool SetSearchTerms(const std::vector<std::string>& search_terms); 45 46 // Starts sending updates and sends a capped amount of downloads. Tracks which 47 // downloads have been sent. Re-call this to send more. 48 void StartAndSendChunk(); 49 50 // Stops sending updates to the page. 51 void Stop(); 52 53 content::DownloadManager* GetMainNotifierManager() const; 54 content::DownloadManager* GetOriginalNotifierManager() const; 55 56 // AllDownloadItemNotifier::Observer: 57 void OnDownloadCreated(content::DownloadManager* manager, 58 download::DownloadItem* download_item) override; 59 void OnDownloadUpdated(content::DownloadManager* manager, 60 download::DownloadItem* download_item) override; 61 void OnDownloadRemoved(content::DownloadManager* manager, 62 download::DownloadItem* download_item) override; 63 64 protected: 65 // Testing constructor. 66 DownloadsListTracker(content::DownloadManager* download_manager, 67 mojo::PendingRemote<downloads::mojom::Page> page, 68 base::Callback<bool(const download::DownloadItem&)>); 69 70 // Creates a dictionary value that's sent to the page as JSON. 71 virtual downloads::mojom::DataPtr CreateDownloadData( 72 download::DownloadItem* item) const; 73 74 // Exposed for testing. 75 bool IsIncognito(const download::DownloadItem& item) const; 76 77 const download::DownloadItem* GetItemForTesting(size_t index) const; 78 79 void SetChunkSizeForTesting(size_t chunk_size); 80 81 private: 82 struct StartTimeComparator { 83 bool operator()(const download::DownloadItem* a, 84 const download::DownloadItem* b) const; 85 }; 86 using SortedSet = std::set<download::DownloadItem*, StartTimeComparator>; 87 88 // Called by both constructors to initialize common state. 89 void Init(); 90 91 // Clears and re-inserts all downloads items into |sorted_items_|. 92 void RebuildSortedItems(); 93 94 // Whether |item| should show on the current page. 95 bool ShouldShow(const download::DownloadItem& item) const; 96 97 // Returns the index of |item| in |sorted_items_|. 98 size_t GetIndex(const SortedSet::iterator& item) const; 99 100 // Calls "insertItems" if sending updates and the page knows about |insert|. 101 void InsertItem(const SortedSet::iterator& insert); 102 103 // Calls "updateItem" if sending updates and the page knows about |update|. 104 void UpdateItem(const SortedSet::iterator& update); 105 106 // Removes the item that corresponds to |remove| and sends "removeItems" 107 // if sending updates. 108 void RemoveItem(const SortedSet::iterator& remove); 109 110 download::AllDownloadItemNotifier main_notifier_; 111 std::unique_ptr<download::AllDownloadItemNotifier> original_notifier_; 112 113 mojo::Remote<downloads::mojom::Page> page_; 114 115 // Callback used to determine if an item should show on the page. Set to 116 // |ShouldShow()| in default constructor, passed in while testing. 117 base::Callback<bool(const download::DownloadItem&)> should_show_; 118 119 // When this is true, all changes to downloads that affect the page are sent 120 // via JavaScript. 121 bool sending_updates_ = false; 122 123 SortedSet sorted_items_; 124 125 // The number of items sent to the page so far. 126 size_t sent_to_page_ = 0u; 127 128 // The maximum number of items sent to the page at a time. 129 size_t chunk_size_ = 20u; 130 131 // Current search terms. 132 std::vector<base::string16> search_terms_; 133 134 DISALLOW_COPY_AND_ASSIGN(DownloadsListTracker); 135 }; 136 137 #endif // CHROME_BROWSER_UI_WEBUI_DOWNLOADS_DOWNLOADS_LIST_TRACKER_H_ 138