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 item is persisted. 71 static bool IsPersisted(content::DownloadItem* item); 72 73 // Neither |manager| nor |history| may be NULL. 74 // DownloadService creates DownloadHistory some time after DownloadManager is 75 // created and destroys DownloadHistory as DownloadManager is shutting down. 76 DownloadHistory( 77 content::DownloadManager* manager, 78 scoped_ptr<HistoryAdapter> history); 79 80 virtual ~DownloadHistory(); 81 82 void AddObserver(Observer* observer); 83 void RemoveObserver(Observer* observer); 84 85 private: 86 typedef std::set<content::DownloadItem*> ItemSet; 87 88 // Callback from |history_| containing all entries in the downloads database 89 // table. 90 void QueryCallback( 91 scoped_ptr<std::vector<history::DownloadRow> > infos); 92 93 // May add |item| to |history_|. 94 void MaybeAddToHistory(content::DownloadItem* item); 95 96 // Callback from |history_| when an item was successfully inserted into the 97 // database. 98 void ItemAdded(uint32 id, bool success); 99 100 // AllDownloadItemNotifier::Observer 101 virtual void OnDownloadCreated( 102 content::DownloadManager* manager, content::DownloadItem* item) OVERRIDE; 103 virtual void OnDownloadUpdated( 104 content::DownloadManager* manager, content::DownloadItem* item) OVERRIDE; 105 virtual void OnDownloadOpened( 106 content::DownloadManager* manager, content::DownloadItem* item) OVERRIDE; 107 virtual void OnDownloadRemoved( 108 content::DownloadManager* manager, content::DownloadItem* item) OVERRIDE; 109 110 // Schedule a record to be removed from |history_| the next time 111 // RemoveDownloadsBatch() runs. Schedule RemoveDownloadsBatch() to be run soon 112 // if it isn't already scheduled. 113 void ScheduleRemoveDownload(uint32 download_id); 114 115 // Removes all |removing_ids_| from |history_|. 116 void RemoveDownloadsBatch(); 117 118 AllDownloadItemNotifier notifier_; 119 120 scoped_ptr<HistoryAdapter> history_; 121 122 // Identifier of the item being created in QueryCallback(), matched up with 123 // created items in OnDownloadCreated() so that the item is not re-added to 124 // the database. 125 uint32 loading_id_; 126 127 // Identifiers of items that are scheduled for removal from history, to 128 // facilitate batching removals together for database efficiency. 129 IdSet removing_ids_; 130 131 // |GetId()|s of items that were removed while they were being added, so that 132 // they can be removed when the database finishes adding them. 133 // TODO(benjhayden) Can this be removed now that it doesn't need to wait for 134 // the db_handle, and can rely on PostTask sequentiality? 135 IdSet removed_while_adding_; 136 137 // Count the number of items in the history for UMA. 138 int64 history_size_; 139 140 ObserverList<Observer> observers_; 141 142 base::WeakPtrFactory<DownloadHistory> weak_ptr_factory_; 143 144 DISALLOW_COPY_AND_ASSIGN(DownloadHistory); 145 }; 146 147 #endif // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_HISTORY_H_ 148