Home | History | Annotate | Download | only in download
      1 // Copyright (c) 2010 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 #include "chrome/browser/download/download_history.h"
      6 
      7 #include "base/logging.h"
      8 #include "chrome/browser/history/download_create_info.h"
      9 #include "chrome/browser/history/history_marshaling.h"
     10 #include "chrome/browser/download/download_item.h"
     11 #include "chrome/browser/profiles/profile.h"
     12 
     13 // Our download table ID starts at 1, so we use 0 to represent a download that
     14 // has started, but has not yet had its data persisted in the table. We use fake
     15 // database handles in incognito mode starting at -1 and progressively getting
     16 // more negative.
     17 // static
     18 const int DownloadHistory::kUninitializedHandle = 0;
     19 
     20 DownloadHistory::DownloadHistory(Profile* profile)
     21     : profile_(profile),
     22       next_fake_db_handle_(kUninitializedHandle - 1) {
     23   DCHECK(profile);
     24 }
     25 
     26 DownloadHistory::~DownloadHistory() {
     27 }
     28 
     29 void DownloadHistory::Load(HistoryService::DownloadQueryCallback* callback) {
     30   DCHECK(callback);
     31   HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
     32   if (!hs) {
     33     delete callback;
     34     return;
     35   }
     36   hs->QueryDownloads(&history_consumer_, callback);
     37 
     38   // This is the initial load, so do a cleanup of corrupt in-progress entries.
     39   hs->CleanUpInProgressEntries();
     40 }
     41 
     42 void DownloadHistory::AddEntry(
     43     const DownloadCreateInfo& info,
     44     DownloadItem* download_item,
     45     HistoryService::DownloadCreateCallback* callback) {
     46   // Do not store the download in the history database for a few special cases:
     47   // - incognito mode (that is the point of this mode)
     48   // - extensions (users don't think of extension installation as 'downloading')
     49   // - temporary download, like in drag-and-drop
     50   // - history service is not available (e.g. in tests)
     51   // We have to make sure that these handles don't collide with normal db
     52   // handles, so we use a negative value. Eventually, they could overlap, but
     53   // you'd have to do enough downloading that your ISP would likely stab you in
     54   // the neck first. YMMV.
     55   // TODO(paulg) see bug 958058. EXPLICIT_ACCESS below is wrong.
     56   HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
     57   if (download_item->is_otr() || download_item->is_extension_install() ||
     58       download_item->is_temporary() || !hs) {
     59     callback->RunWithParams(
     60         history::DownloadCreateRequest::TupleType(info, GetNextFakeDbHandle()));
     61     delete callback;
     62     return;
     63   }
     64 
     65   hs->CreateDownload(info, &history_consumer_, callback);
     66 }
     67 
     68 void DownloadHistory::UpdateEntry(DownloadItem* download_item) {
     69   // Don't store info in the database if the download was initiated while in
     70   // incognito mode or if it hasn't been initialized in our database table.
     71   if (download_item->db_handle() <= kUninitializedHandle)
     72     return;
     73 
     74   // TODO(paulg) see bug 958058. EXPLICIT_ACCESS below is wrong.
     75   HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
     76   if (!hs)
     77     return;
     78 
     79   hs->UpdateDownload(download_item->received_bytes(),
     80                      download_item->state(),
     81                      download_item->db_handle());
     82 }
     83 
     84 void DownloadHistory::UpdateDownloadPath(DownloadItem* download_item,
     85                                          const FilePath& new_path) {
     86   // No update necessary if the download was initiated while in incognito mode.
     87   if (download_item->db_handle() <= kUninitializedHandle)
     88     return;
     89 
     90   // TODO(paulg) see bug 958058. EXPLICIT_ACCESS below is wrong.
     91   HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
     92   if (hs)
     93     hs->UpdateDownloadPath(new_path, download_item->db_handle());
     94 }
     95 
     96 void DownloadHistory::RemoveEntry(DownloadItem* download_item) {
     97   // No update necessary if the download was initiated while in incognito mode.
     98   if (download_item->db_handle() <= kUninitializedHandle)
     99     return;
    100 
    101   // TODO(paulg) see bug 958058. EXPLICIT_ACCESS below is wrong.
    102   HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
    103   if (hs)
    104     hs->RemoveDownload(download_item->db_handle());
    105 }
    106 
    107 void DownloadHistory::RemoveEntriesBetween(const base::Time remove_begin,
    108                                            const base::Time remove_end) {
    109   // TODO(paulg) see bug 958058. EXPLICIT_ACCESS below is wrong.
    110   HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
    111   if (hs)
    112     hs->RemoveDownloadsBetween(remove_begin, remove_end);
    113 }
    114 
    115 int64 DownloadHistory::GetNextFakeDbHandle() {
    116   return next_fake_db_handle_--;
    117 }
    118