Home | History | Annotate | Download | only in 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.
     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