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