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 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_DOWNLOAD_DOWNLOAD_HISTORY_H_ 6 #define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_HISTORY_H_ 7 8 #include <stdint.h> 9 10 #include <set> 11 #include <vector> 12 13 #include "base/callback.h" 14 #include "base/macros.h" 15 #include "base/memory/weak_ptr.h" 16 #include "base/observer_list.h" 17 #include "components/download/content/public/all_download_item_notifier.h" 18 #include "components/download/public/common/download_item.h" 19 #include "components/history/core/browser/history_service.h" 20 #include "content/public/browser/download_manager.h" 21 22 namespace history { 23 struct DownloadRow; 24 } // namespace history 25 26 // Observes a single DownloadManager and all its DownloadItems, keeping the 27 // DownloadDatabase up to date. 28 class DownloadHistory : public download::AllDownloadItemNotifier::Observer { 29 public: 30 typedef std::set<uint32_t> IdSet; 31 32 // Caller must guarantee that HistoryService outlives HistoryAdapter. 33 class HistoryAdapter { 34 public: 35 explicit HistoryAdapter(history::HistoryService* history); 36 virtual ~HistoryAdapter(); 37 38 virtual void QueryDownloads( 39 history::HistoryService::DownloadQueryCallback callback); 40 41 virtual void CreateDownload( 42 const history::DownloadRow& info, 43 history::HistoryService::DownloadCreateCallback callback); 44 45 virtual void UpdateDownload(const history::DownloadRow& data, 46 bool should_commit_immediately); 47 48 virtual void RemoveDownloads(const std::set<uint32_t>& ids); 49 50 private: 51 history::HistoryService* history_; 52 DISALLOW_COPY_AND_ASSIGN(HistoryAdapter); 53 }; 54 55 class Observer { 56 public: 57 Observer(); 58 virtual ~Observer(); 59 60 // Fires when a download is added to or updated in the database, just after 61 // the task is posted to the history thread. OnDownloadStored(download::DownloadItem * item,const history::DownloadRow & info)62 virtual void OnDownloadStored(download::DownloadItem* item, 63 const history::DownloadRow& info) {} 64 65 // Fires when RemoveDownloads messages are sent to the DB thread. OnDownloadsRemoved(const IdSet & ids)66 virtual void OnDownloadsRemoved(const IdSet& ids) {} 67 68 // Fires when the DownloadHistory completes the initial history query. 69 // Unlike the other observer methods, this one is invoked if the initial 70 // history query has already completed by the time the caller calls 71 // AddObserver(). OnHistoryQueryComplete()72 virtual void OnHistoryQueryComplete() {} 73 74 // Fires when the DownloadHistory is being destroyed so that implementors 75 // can RemoveObserver() and nullify their DownloadHistory*s. OnDownloadHistoryDestroyed()76 virtual void OnDownloadHistoryDestroyed() {} 77 }; 78 79 // Returns true if the download is persisted. Not reliable when called from 80 // within a DownloadManager::Observer::OnDownloadCreated handler since the 81 // persisted state may not yet have been updated for a download that was 82 // restored from history. 83 static bool IsPersisted(const download::DownloadItem* item); 84 85 // Neither |manager| nor |history| may be NULL. 86 // DownloadService creates DownloadHistory some time after DownloadManager is 87 // created and destroys DownloadHistory as DownloadManager is shutting down. 88 DownloadHistory(content::DownloadManager* manager, 89 std::unique_ptr<HistoryAdapter> history); 90 91 ~DownloadHistory() override; 92 93 void AddObserver(Observer* observer); 94 void RemoveObserver(Observer* observer); 95 96 private: 97 // Callback from |history_| containing all entries in the downloads database 98 // table. 99 void QueryCallback(std::vector<history::DownloadRow> rows); 100 101 // Called to create all history downloads. 102 void LoadHistoryDownloads(std::vector<history::DownloadRow> rows); 103 104 // May add |item| to |history_|. 105 void MaybeAddToHistory(download::DownloadItem* item); 106 107 // Callback from |history_| when an item was successfully inserted into the 108 // database. 109 void ItemAdded(uint32_t id, const history::DownloadRow& info, bool success); 110 111 // AllDownloadItemNotifier::Observer 112 void OnDownloadCreated(content::DownloadManager* manager, 113 download::DownloadItem* item) override; 114 void OnDownloadUpdated(content::DownloadManager* manager, 115 download::DownloadItem* item) override; 116 void OnDownloadOpened(content::DownloadManager* manager, 117 download::DownloadItem* item) override; 118 void OnDownloadRemoved(content::DownloadManager* manager, 119 download::DownloadItem* item) override; 120 121 // Schedule a record to be removed from |history_| the next time 122 // RemoveDownloadsBatch() runs. Schedule RemoveDownloadsBatch() to be run soon 123 // if it isn't already scheduled. 124 void ScheduleRemoveDownload(uint32_t download_id); 125 126 // Removes all |removing_ids_| from |history_|. 127 void RemoveDownloadsBatch(); 128 129 // Called when a download was restored from history. 130 void OnDownloadRestoredFromHistory(download::DownloadItem* item); 131 132 // Check whether an download item needs be updated or added to history DB. 133 bool NeedToUpdateDownloadHistory(download::DownloadItem* item); 134 135 download::AllDownloadItemNotifier notifier_; 136 137 std::unique_ptr<HistoryAdapter> history_; 138 139 // Identifier of the item being created in QueryCallback(), matched up with 140 // created items in OnDownloadCreated() so that the item is not re-added to 141 // the database. 142 uint32_t loading_id_; 143 144 // Identifiers of items that are scheduled for removal from history, to 145 // facilitate batching removals together for database efficiency. 146 IdSet removing_ids_; 147 148 // |GetId()|s of items that were removed while they were being added, so that 149 // they can be removed when the database finishes adding them. 150 // TODO(benjhayden) Can this be removed now that it doesn't need to wait for 151 // the db_handle, and can rely on PostTask sequentiality? 152 IdSet removed_while_adding_; 153 154 bool initial_history_query_complete_; 155 156 base::ObserverList<Observer>::Unchecked observers_; 157 158 base::WeakPtrFactory<DownloadHistory> weak_ptr_factory_{this}; 159 160 DISALLOW_COPY_AND_ASSIGN(DownloadHistory); 161 }; 162 163 #endif // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_HISTORY_H_ 164