Index: chrome/browser/download/download_history.h |
diff --git a/chrome/browser/download/download_history.h b/chrome/browser/download/download_history.h |
index 1a831ed706048439d371eb0bdce1c48ce5b11a4c..4a27bbb428a085bb7ded963207088e4fb0449c55 100644 |
--- a/chrome/browser/download/download_history.h |
+++ b/chrome/browser/download/download_history.h |
@@ -5,87 +5,149 @@ |
#ifndef CHROME_BROWSER_DOWNLOAD_DOWNLOAD_HISTORY_H_ |
#define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_HISTORY_H_ |
-#include <map> |
+#include <set> |
+#include <vector> |
#include "base/basictypes.h" |
#include "base/callback.h" |
+#include "base/memory/weak_ptr.h" |
+#include "base/observer_list.h" |
#include "chrome/browser/common/cancelable_request.h" |
+#include "chrome/browser/download/all_download_item_notifier.h" |
#include "chrome/browser/history/history.h" |
+#include "content/public/browser/download_item.h" |
+#include "content/public/browser/download_manager.h" |
-class Profile; |
+namespace history { |
+struct DownloadRow; |
+} // namespace history |
-namespace base { |
-class Time; |
-} |
+// Observes a single DownloadManager and all its DownloadItems, keeping the |
+// DownloadDatabase up to date. |
+class DownloadHistory : public AllDownloadItemNotifier::Observer { |
+ public: |
+ typedef std::set<int32> IdSet; |
-namespace content { |
-class DownloadItem; |
-} |
+ // Caller must guarantee that HistoryService outlives HistoryAdapter. |
+ class HistoryAdapter { |
+ public: |
+ explicit HistoryAdapter(HistoryService* history); |
+ virtual ~HistoryAdapter(); |
-// Interacts with the HistoryService on behalf of the download subsystem. |
-class DownloadHistory { |
- public: |
- typedef base::Callback<void(bool)> VisitedBeforeDoneCallback; |
+ virtual void QueryDownloads( |
+ const HistoryService::DownloadQueryCallback& callback); |
+ |
+ virtual void CreateDownload( |
+ const history::DownloadRow& info, |
+ const HistoryService::DownloadCreateCallback& callback); |
+ |
+ virtual void UpdateDownload(const history::DownloadRow& data); |
- explicit DownloadHistory(Profile* profile); |
- ~DownloadHistory(); |
+ virtual void RemoveDownloads(const std::set<int64>& db_handles); |
- // Retrieves the next_id counter from the sql meta_table. |
- // Should be much faster than Load so that we may delay downloads until after |
- // this call with minimal performance penalty. |
- void GetNextId(const HistoryService::DownloadNextIdCallback& callback); |
+ private: |
+ HistoryService* history_; |
+ CancelableRequestConsumer consumer_; |
+ DISALLOW_COPY_AND_ASSIGN(HistoryAdapter); |
+ }; |
- // Retrieves DownloadCreateInfos saved in the history. |
- void Load(const HistoryService::DownloadQueryCallback& callback); |
+ class Observer { |
+ public: |
+ Observer(); |
+ virtual ~Observer(); |
- // Checks whether |referrer_url| has been visited before today. This takes |
- // ownership of |callback|. |
- void CheckVisitedReferrerBefore(int32 download_id, |
- const GURL& referrer_url, |
- const VisitedBeforeDoneCallback& callback); |
+ // Fires when a download is added to or updated in the database. When |
+ // downloads are first added, this fires after the callback from the |
+ // database so that |info| includes the |db_handle|. When downloads are |
+ // updated, this fires right after the message is sent to the database. |
+ // |info| always includes the |db_handle|. |
+ virtual void OnDownloadStored(content::DownloadItem* item, |
+ const history::DownloadRow& info) { |
+ } |
- // Adds a new entry for a download to the history database. |
- void AddEntry(content::DownloadItem* download_item, |
- const HistoryService::DownloadCreateCallback& callback); |
+ // Fires when RemoveDownloads messages are sent to the DB thread. |
+ virtual void OnDownloadsRemoved(const IdSet& ids) {} |
- // Updates the history entry for |download_item|. |
- void UpdateEntry(content::DownloadItem* download_item); |
+ // Fires when the DownloadHistory is being destroyed so that implementors |
+ // can RemoveObserver() and nullify their DownloadHistory*s. |
+ virtual void OnDownloadHistoryDestroyed() {} |
+ }; |
- // Updates the download path for |download_item| to |new_path|. |
- void UpdateDownloadPath(content::DownloadItem* download_item, |
- const FilePath& new_path); |
+ // Returns true if the item is persisted. |
+ static bool IsPersisted(content::DownloadItem* item); |
- // Removes |download_item| from the history database. |
- void RemoveEntry(content::DownloadItem* download_item); |
+ // Neither |manager| nor |history| may be NULL. |
+ // DownloadService creates DownloadHistory some time after DownloadManager is |
+ // created and destroys DownloadHistory as DownloadManager is shutting down. |
+ DownloadHistory( |
+ content::DownloadManager* manager, |
+ scoped_ptr<HistoryAdapter> history); |
- // Removes download-related history entries in the given time range. |
- void RemoveEntriesBetween(const base::Time remove_begin, |
- const base::Time remove_end); |
+ virtual ~DownloadHistory(); |
- // Returns a new unique database handle which will not collide with real ones. |
- int64 GetNextFakeDbHandle(); |
+ void AddObserver(Observer* observer); |
+ void RemoveObserver(Observer* observer); |
private: |
- typedef std::map<HistoryService::Handle, VisitedBeforeDoneCallback> |
- VisitedBeforeRequestsMap; |
+ typedef std::set<int64> HandleSet; |
+ typedef std::set<content::DownloadItem*> ItemSet; |
+ |
+ // Callback from |history_| containing all entries in the downloads database |
+ // table. |
+ void QueryCallback( |
+ std::vector<history::DownloadRow>* infos); |
+ |
+ // May add |item| to |history_|. |
+ void MaybeAddToHistory(content::DownloadItem* item); |
+ |
+ // Callback from |history_| when an item was successfully inserted into the |
+ // database. |
+ void ItemAdded(int32 id, int64 db_handle); |
+ |
+ // AllDownloadItemNotifier::Observer |
+ virtual void OnDownloadCreated( |
+ content::DownloadManager* manager, content::DownloadItem* item) OVERRIDE; |
+ virtual void OnDownloadUpdated( |
+ content::DownloadManager* manager, content::DownloadItem* item) OVERRIDE; |
+ virtual void OnDownloadOpened( |
+ content::DownloadManager* manager, content::DownloadItem* item) OVERRIDE; |
+ virtual void OnDownloadRemoved( |
+ content::DownloadManager* manager, content::DownloadItem* item) OVERRIDE; |
+ |
+ // Schedule a record to be removed from |history_| the next time |
+ // RemoveDownloadsBatch() runs. Schedule RemoveDownloadsBatch() to be run soon |
+ // if it isn't already scheduled. |
+ void ScheduleRemoveDownload(int32 download_id, int64 db_handle); |
+ |
+ // Removes all |removing_handles_| from |history_|. |
+ void RemoveDownloadsBatch(); |
+ |
+ |
+ AllDownloadItemNotifier notifier_; |
+ |
+ scoped_ptr<HistoryAdapter> history_; |
+ |
+ // |db_handle| of the item being created in response to QueryCallback(), |
+ // matched up with created items in OnDownloadCreated() so that the item is |
+ // not re-added to the database. For items not created by QueryCallback(), |
+ // this is DownloadDatabase::kUninitializedHandle. |
+ int64 loading_db_handle_; |
- void OnGotVisitCountToHost(HistoryService::Handle handle, |
- bool found_visits, |
- int count, |
- base::Time first_visit); |
+ // |db_handles| and |ids| of items that are scheduled for removal from |
+ // history, to facilitate batching removals together for database efficiency. |
+ HandleSet removing_handles_; |
+ IdSet removing_ids_; |
- Profile* profile_; |
+ // |GetId()|s of items that were removed while they were being added, so that |
+ // they can be removed when their db_handles are received from the database. |
+ IdSet removed_while_adding_; |
- // In case we don't have a valid db_handle, we use |fake_db_handle_| instead. |
- // This is useful for incognito mode or when the history database is offline. |
- // Downloads are expected to have unique handles, so we decrement the next |
- // fake handle value on every use. |
- int64 next_fake_db_handle_; |
+ // Count the number of items in the history for UMA. |
+ int64 history_size_; |
- CancelableRequestConsumer history_consumer_; |
+ ObserverList<Observer> observers_; |
- // The outstanding requests made by CheckVisitedReferrerBefore(). |
- VisitedBeforeRequestsMap visited_before_requests_; |
+ base::WeakPtrFactory<DownloadHistory> weak_ptr_factory_; |
DISALLOW_COPY_AND_ASSIGN(DownloadHistory); |
}; |