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