• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
OnDownloadStored(content::DownloadItem * item,const history::DownloadRow & info)59     virtual void OnDownloadStored(content::DownloadItem* item,
60                                   const history::DownloadRow& info) {}
61 
62     // Fires when RemoveDownloads messages are sent to the DB thread.
OnDownloadsRemoved(const IdSet & ids)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.
OnDownloadHistoryDestroyed()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