Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Side by Side Diff: content/browser/download/download_file_manager.cc

Issue 10799005: Replace the DownloadFileManager with direct ownership (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed Windows compile error. Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 #include "content/browser/download/download_file_manager.h"
6
7 #include <set>
8 #include <string>
9
10 #include "base/bind.h"
11 #include "base/file_util.h"
12 #include "base/logging.h"
13 #include "base/stl_util.h"
14 #include "base/utf_string_conversions.h"
15 #include "content/browser/download/base_file.h"
16 #include "content/browser/download/download_create_info.h"
17 #include "content/browser/download/download_file_impl.h"
18 #include "content/browser/download/download_interrupt_reasons_impl.h"
19 #include "content/browser/download/download_request_handle.h"
20 #include "content/browser/download/download_stats.h"
21 #include "content/browser/power_save_blocker.h"
22 #include "content/browser/web_contents/web_contents_impl.h"
23 #include "content/public/browser/browser_thread.h"
24 #include "content/public/browser/download_manager.h"
25 #include "content/public/browser/download_manager_delegate.h"
26 #include "googleurl/src/gurl.h"
27 #include "net/base/io_buffer.h"
28
29 using content::BrowserThread;
30 using content::DownloadFile;
31 using content::DownloadId;
32 using content::DownloadManager;
33
34 namespace {
35
36 class DownloadFileFactoryImpl
37 : public DownloadFileManager::DownloadFileFactory {
38 public:
39 DownloadFileFactoryImpl() {}
40
41 virtual content::DownloadFile* CreateFile(
42 DownloadCreateInfo* info,
43 scoped_ptr<content::ByteStreamReader> stream,
44 DownloadManager* download_manager,
45 bool calculate_hash,
46 const net::BoundNetLog& bound_net_log) OVERRIDE;
47 };
48
49 DownloadFile* DownloadFileFactoryImpl::CreateFile(
50 DownloadCreateInfo* info,
51 scoped_ptr<content::ByteStreamReader> stream,
52 DownloadManager* download_manager,
53 bool calculate_hash,
54 const net::BoundNetLog& bound_net_log) {
55 return new DownloadFileImpl(
56 info, stream.Pass(), new DownloadRequestHandle(info->request_handle),
57 download_manager, calculate_hash,
58 scoped_ptr<content::PowerSaveBlocker>(
59 new content::PowerSaveBlocker(
60 content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
61 "Download in progress")).Pass(),
62 bound_net_log);
63 }
64
65 } // namespace
66
67 DownloadFileManager::DownloadFileManager(DownloadFileFactory* factory)
68 : download_file_factory_(factory) {
69 if (download_file_factory_ == NULL)
70 download_file_factory_.reset(new DownloadFileFactoryImpl);
71 }
72
73 DownloadFileManager::~DownloadFileManager() {
74 DCHECK(downloads_.empty());
75 }
76
77 void DownloadFileManager::Shutdown() {
78 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
79 BrowserThread::PostTask(
80 BrowserThread::FILE, FROM_HERE,
81 base::Bind(&DownloadFileManager::OnShutdown, this));
82 }
83
84 void DownloadFileManager::OnShutdown() {
85 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
86 STLDeleteValues(&downloads_);
87 }
88
89 void DownloadFileManager::CreateDownloadFile(
90 scoped_ptr<DownloadCreateInfo> info,
91 scoped_ptr<content::ByteStreamReader> stream,
92 scoped_refptr<DownloadManager> download_manager, bool get_hash,
93 const net::BoundNetLog& bound_net_log,
94 const CreateDownloadFileCallback& callback) {
95 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
96 DCHECK(info.get());
97 VLOG(20) << __FUNCTION__ << "()" << " info = " << info->DebugString();
98
99 scoped_ptr<DownloadFile> download_file(download_file_factory_->CreateFile(
100 info.get(), stream.Pass(), download_manager, get_hash, bound_net_log));
101
102 content::DownloadInterruptReason interrupt_reason(
103 download_file->Initialize());
104 if (interrupt_reason == content::DOWNLOAD_INTERRUPT_REASON_NONE) {
105 DCHECK(GetDownloadFile(info->download_id) == NULL);
106 downloads_[info->download_id] = download_file.release();
107 }
108
109 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
110 base::Bind(callback, interrupt_reason));
111 }
112
113 DownloadFile* DownloadFileManager::GetDownloadFile(
114 DownloadId global_id) {
115 DownloadFileMap::iterator it = downloads_.find(global_id);
116 return it == downloads_.end() ? NULL : it->second;
117 }
118
119 // This method will be sent via a user action, or shutdown on the UI thread, and
120 // run on the download thread. Since this message has been sent from the UI
121 // thread, the download may have already completed and won't exist in our map.
122 void DownloadFileManager::CancelDownload(DownloadId global_id) {
123 VLOG(20) << __FUNCTION__ << "()" << " id = " << global_id;
124 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
125 DownloadFileMap::iterator it = downloads_.find(global_id);
126 if (it == downloads_.end())
127 return;
128
129 DownloadFile* download_file = it->second;
130 VLOG(20) << __FUNCTION__ << "()"
131 << " download_file = " << download_file->DebugString();
132 download_file->Cancel();
133
134 EraseDownload(global_id);
135 }
136
137 void DownloadFileManager::CompleteDownload(
138 DownloadId global_id, const base::Closure& callback) {
139 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
140
141 if (!ContainsKey(downloads_, global_id))
142 return;
143
144 DownloadFile* download_file = downloads_[global_id];
145
146 VLOG(20) << " " << __FUNCTION__ << "()"
147 << " id = " << global_id
148 << " download_file = " << download_file->DebugString();
149
150 // Done here on Windows so that anti-virus scanners invoked by
151 // the attachment service actually see the data; see
152 // http://crbug.com/127999.
153 // Done here for mac because we only want to do this once; see
154 // http://crbug.com/13120 for details.
155 // Other platforms don't currently do source annotation.
156 download_file->AnnotateWithSourceInformation();
157
158 download_file->Detach();
159
160 EraseDownload(global_id);
161
162 // Notify our caller we've let it go.
163 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
164 }
165
166 void DownloadFileManager::OnDownloadManagerShutdown(DownloadManager* manager) {
167 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
168 DCHECK(manager);
169
170 std::set<DownloadFile*> to_remove;
171
172 for (DownloadFileMap::iterator i = downloads_.begin();
173 i != downloads_.end(); ++i) {
174 DownloadFile* download_file = i->second;
175 if (download_file->GetDownloadManager() == manager) {
176 download_file->CancelDownloadRequest();
177 to_remove.insert(download_file);
178 }
179 }
180
181 for (std::set<DownloadFile*>::iterator i = to_remove.begin();
182 i != to_remove.end(); ++i) {
183 downloads_.erase((*i)->GlobalId());
184 delete *i;
185 }
186 }
187
188 // Actions from the UI thread and run on the download thread
189
190 void DownloadFileManager::RenameDownloadFile(
191 DownloadId global_id,
192 const FilePath& full_path,
193 bool overwrite_existing_file,
194 const RenameCompletionCallback& callback) {
195 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
196 DownloadFile* download_file = GetDownloadFile(global_id);
197 if (!download_file) {
198 BrowserThread::PostTask(
199 BrowserThread::UI, FROM_HERE,
200 base::Bind(callback, content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED,
201 FilePath()));
202 return;
203 }
204
205 download_file->Rename(full_path, overwrite_existing_file, callback);
206 }
207
208 int DownloadFileManager::NumberOfActiveDownloads() const {
209 return downloads_.size();
210 }
211
212 void DownloadFileManager::EraseDownload(DownloadId global_id) {
213 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
214
215 if (!ContainsKey(downloads_, global_id))
216 return;
217
218 DownloadFile* download_file = downloads_[global_id];
219
220 VLOG(20) << " " << __FUNCTION__ << "()"
221 << " id = " << global_id
222 << " download_file = " << download_file->DebugString();
223
224 downloads_.erase(global_id);
225
226 delete download_file;
227 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698