15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_BROWSER_DOWNLOAD_DOWNLOAD_HISTORY_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_HISTORY_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <set>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/weak_ptr.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/observer_list.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/download/all_download_item_notifier.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/history_service.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/download_item.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/download_manager.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace history {
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct DownloadRow;
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace history
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Observes a single DownloadManager and all its DownloadItems, keeping the
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// DownloadDatabase up to date.
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class DownloadHistory : public AllDownloadItemNotifier::Observer {
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  typedef std::set<uint32> IdSet;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Caller must guarantee that HistoryService outlives HistoryAdapter.
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  class HistoryAdapter {
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   public:
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    explicit HistoryAdapter(HistoryService* history);
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual ~HistoryAdapter();
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual void QueryDownloads(
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        const HistoryService::DownloadQueryCallback& callback);
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual void CreateDownload(
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        const history::DownloadRow& info,
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        const HistoryService::DownloadCreateCallback& callback);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual void UpdateDownload(const history::DownloadRow& data);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    virtual void RemoveDownloads(const std::set<uint32>& ids);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   private:
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    HistoryService* history_;
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DISALLOW_COPY_AND_ASSIGN(HistoryAdapter);
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  class Observer {
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   public:
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Observer();
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual ~Observer();
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // Fires when a download is added to or updated in the database, just after
587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // the task is posted to the history thread.
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual void OnDownloadStored(content::DownloadItem* item,
607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                  const history::DownloadRow& info) {}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Fires when RemoveDownloads messages are sent to the DB thread.
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual void OnDownloadsRemoved(const IdSet& ids) {}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Fires when the DownloadHistory is being destroyed so that implementors
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // can RemoveObserver() and nullify their DownloadHistory*s.
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual void OnDownloadHistoryDestroyed() {}
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Returns true if the download is persisted. Not reliable when called from
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // within a DownloadManager::Observer::OnDownloadCreated handler since the
72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // persisted state may not yet have been updated for a download that was
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // restored from history.
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  static bool IsPersisted(const content::DownloadItem* item);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Neither |manager| nor |history| may be NULL.
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // DownloadService creates DownloadHistory some time after DownloadManager is
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // created and destroys DownloadHistory as DownloadManager is shutting down.
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DownloadHistory(
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::DownloadManager* manager,
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scoped_ptr<HistoryAdapter> history);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~DownloadHistory();
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AddObserver(Observer* observer);
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void RemoveObserver(Observer* observer);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Returns true if the download was restored from history. Safe to call from
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // within a DownloadManager::Observer::OnDownloadCreated handler and can be
90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // used to distinguish between downloads that were created due to new requests
91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // vs. downloads that were created due to being restored from history. Note
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // that the return value is only reliable for downloads that were restored by
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // this specific DownloadHistory instance.
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool WasRestoredFromHistory(const content::DownloadItem* item) const;
95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef std::set<content::DownloadItem*> ItemSet;
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Callback from |history_| containing all entries in the downloads database
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // table.
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void QueryCallback(
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scoped_ptr<std::vector<history::DownloadRow> > infos);
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // May add |item| to |history_|.
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void MaybeAddToHistory(content::DownloadItem* item);
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Callback from |history_| when an item was successfully inserted into the
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // database.
1097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void ItemAdded(uint32 id, bool success);
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // AllDownloadItemNotifier::Observer
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnDownloadCreated(
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::DownloadManager* manager, content::DownloadItem* item) OVERRIDE;
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnDownloadUpdated(
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::DownloadManager* manager, content::DownloadItem* item) OVERRIDE;
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnDownloadOpened(
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::DownloadManager* manager, content::DownloadItem* item) OVERRIDE;
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnDownloadRemoved(
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::DownloadManager* manager, content::DownloadItem* item) OVERRIDE;
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Schedule a record to be removed from |history_| the next time
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // RemoveDownloadsBatch() runs. Schedule RemoveDownloadsBatch() to be run soon
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // if it isn't already scheduled.
1247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void ScheduleRemoveDownload(uint32 download_id);
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Removes all |removing_ids_| from |history_|.
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void RemoveDownloadsBatch();
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AllDownloadItemNotifier notifier_;
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HistoryAdapter> history_;
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Identifier of the item being created in QueryCallback(), matched up with
1347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // created items in OnDownloadCreated() so that the item is not re-added to
1357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // the database.
1367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  uint32 loading_id_;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Identifiers of items that are scheduled for removal from history, to
1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // facilitate batching removals together for database efficiency.
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  IdSet removing_ids_;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |GetId()|s of items that were removed while they were being added, so that
1437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // they can be removed when the database finishes adding them.
1447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // TODO(benjhayden) Can this be removed now that it doesn't need to wait for
1457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // the db_handle, and can rely on PostTask sequentiality?
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  IdSet removed_while_adding_;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Count the number of items in the history for UMA.
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 history_size_;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ObserverList<Observer> observers_;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::WeakPtrFactory<DownloadHistory> weak_ptr_factory_;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DownloadHistory);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_HISTORY_H_
159