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

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

Issue 8351052: Created a DownloadManager interface, for use in unit tests.. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merged with trunk Created 9 years, 1 month 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
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/download/download_manager.h" 5 #include "content/browser/download/download_manager_impl.h"
6 6
7 #include <iterator> 7 #include <iterator>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
11 #include "base/file_util.h" 11 #include "base/file_util.h"
12 #include "base/i18n/case_conversion.h" 12 #include "base/i18n/case_conversion.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/stl_util.h" 14 #include "base/stl_util.h"
15 #include "base/stringprintf.h" 15 #include "base/stringprintf.h"
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 resource_dispatcher_host->BeginDownload( 65 resource_dispatcher_host->BeginDownload(
66 request, save_info, true, 66 request, save_info, true,
67 DownloadResourceHandler::OnStartedCallback(), 67 DownloadResourceHandler::OnStartedCallback(),
68 render_params.render_process_id_, 68 render_params.render_process_id_,
69 render_params.render_view_id_, 69 render_params.render_view_id_,
70 *context); 70 *context);
71 } 71 }
72 72
73 } // namespace 73 } // namespace
74 74
75 DownloadManager::DownloadManager(content::DownloadManagerDelegate* delegate, 75 DownloadManagerImpl::DownloadManagerImpl(
76 DownloadIdFactory* id_factory, 76 content::DownloadManagerDelegate* delegate,
77 DownloadStatusUpdater* status_updater) 77 DownloadIdFactory* id_factory,
78 : shutdown_needed_(false), 78 DownloadStatusUpdater* status_updater)
79 browser_context_(NULL), 79 : shutdown_needed_(false),
80 file_manager_(NULL), 80 browser_context_(NULL),
81 status_updater_((status_updater != NULL) 81 file_manager_(NULL),
82 ? status_updater->AsWeakPtr() 82 status_updater_((status_updater != NULL)
83 : base::WeakPtr<DownloadStatusUpdater>()), 83 ? status_updater->AsWeakPtr()
84 delegate_(delegate), 84 : base::WeakPtr<DownloadStatusUpdater>()),
85 id_factory_(id_factory), 85 delegate_(delegate),
86 largest_db_handle_in_history_(DownloadItem::kUninitializedHandle) { 86 id_factory_(id_factory),
87 largest_db_handle_in_history_(DownloadItem::kUninitializedHandle) {
87 // NOTE(benjhayden): status_updater may be NULL when using 88 // NOTE(benjhayden): status_updater may be NULL when using
88 // TestingBrowserProcess. 89 // TestingBrowserProcess.
89 if (status_updater_.get() != NULL) 90 if (status_updater_.get() != NULL)
90 status_updater_->AddDelegate(this); 91 status_updater_->AddDelegate(this);
91 } 92 }
92 93
93 DownloadManager::~DownloadManager() { 94 DownloadManagerImpl::~DownloadManagerImpl() {
94 DCHECK(!shutdown_needed_); 95 DCHECK(!shutdown_needed_);
95 if (status_updater_.get() != NULL) 96 if (status_updater_.get() != NULL)
96 status_updater_->RemoveDelegate(this); 97 status_updater_->RemoveDelegate(this);
97 } 98 }
98 99
99 DownloadId DownloadManager::GetNextId() { 100 DownloadId DownloadManagerImpl::GetNextId() {
100 return id_factory_->GetNextId(); 101 return id_factory_->GetNextId();
101 } 102 }
102 103
103 void DownloadManager::Shutdown() { 104 void DownloadManagerImpl::Shutdown() {
104 VLOG(20) << __FUNCTION__ << "()" 105 VLOG(20) << __FUNCTION__ << "()"
105 << " shutdown_needed_ = " << shutdown_needed_; 106 << " shutdown_needed_ = " << shutdown_needed_;
106 if (!shutdown_needed_) 107 if (!shutdown_needed_)
107 return; 108 return;
108 shutdown_needed_ = false; 109 shutdown_needed_ = false;
109 110
110 FOR_EACH_OBSERVER(Observer, observers_, ManagerGoingDown()); 111 FOR_EACH_OBSERVER(Observer, observers_, ManagerGoingDown());
111 // TODO(benjhayden): Consider clearing observers_. 112 // TODO(benjhayden): Consider clearing observers_.
112 113
113 if (file_manager_) { 114 if (file_manager_) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 STLDeleteElements(&downloads_to_delete); 161 STLDeleteElements(&downloads_to_delete);
161 162
162 DCHECK(save_page_downloads_.empty()); 163 DCHECK(save_page_downloads_.empty());
163 164
164 file_manager_ = NULL; 165 file_manager_ = NULL;
165 delegate_->Shutdown(); 166 delegate_->Shutdown();
166 167
167 shutdown_needed_ = false; 168 shutdown_needed_ = false;
168 } 169 }
169 170
170 void DownloadManager::GetTemporaryDownloads( 171 void DownloadManagerImpl::GetTemporaryDownloads(
171 const FilePath& dir_path, DownloadVector* result) { 172 const FilePath& dir_path, DownloadVector* result) {
172 DCHECK(result); 173 DCHECK(result);
173 174
174 for (DownloadMap::iterator it = history_downloads_.begin(); 175 for (DownloadMap::iterator it = history_downloads_.begin();
175 it != history_downloads_.end(); ++it) { 176 it != history_downloads_.end(); ++it) {
176 if (it->second->is_temporary() && 177 if (it->second->is_temporary() &&
177 it->second->full_path().DirName() == dir_path) 178 it->second->full_path().DirName() == dir_path)
178 result->push_back(it->second); 179 result->push_back(it->second);
179 } 180 }
180 } 181 }
181 182
182 void DownloadManager::GetAllDownloads( 183 void DownloadManagerImpl::GetAllDownloads(
183 const FilePath& dir_path, DownloadVector* result) { 184 const FilePath& dir_path, DownloadVector* result) {
184 DCHECK(result); 185 DCHECK(result);
185 186
186 for (DownloadMap::iterator it = history_downloads_.begin(); 187 for (DownloadMap::iterator it = history_downloads_.begin();
187 it != history_downloads_.end(); ++it) { 188 it != history_downloads_.end(); ++it) {
188 if (!it->second->is_temporary() && 189 if (!it->second->is_temporary() &&
189 (dir_path.empty() || it->second->full_path().DirName() == dir_path)) 190 (dir_path.empty() || it->second->full_path().DirName() == dir_path))
190 result->push_back(it->second); 191 result->push_back(it->second);
191 } 192 }
192 } 193 }
193 194
194 void DownloadManager::SearchDownloads(const string16& query, 195 void DownloadManagerImpl::SearchDownloads(const string16& query,
195 DownloadVector* result) { 196 DownloadVector* result) {
196 string16 query_lower(base::i18n::ToLower(query)); 197 string16 query_lower(base::i18n::ToLower(query));
197 198
198 for (DownloadMap::iterator it = history_downloads_.begin(); 199 for (DownloadMap::iterator it = history_downloads_.begin();
199 it != history_downloads_.end(); ++it) { 200 it != history_downloads_.end(); ++it) {
200 DownloadItem* download_item = it->second; 201 DownloadItem* download_item = it->second;
201 202
202 if (download_item->is_temporary()) 203 if (download_item->is_temporary())
203 continue; 204 continue;
204 205
205 // Display Incognito downloads only in Incognito window, and vice versa. 206 // Display Incognito downloads only in Incognito window, and vice versa.
206 // The Incognito Downloads page will get the list of non-Incognito downloads 207 // The Incognito Downloads page will get the list of non-Incognito downloads
207 // from its parent profile. 208 // from its parent profile.
208 if (browser_context_->IsOffTheRecord() != download_item->is_otr()) 209 if (browser_context_->IsOffTheRecord() != download_item->is_otr())
209 continue; 210 continue;
210 211
211 if (download_item->MatchesQuery(query_lower)) 212 if (download_item->MatchesQuery(query_lower))
212 result->push_back(download_item); 213 result->push_back(download_item);
213 } 214 }
214 } 215 }
215 216
216 // Query the history service for information about all persisted downloads. 217 // Query the history service for information about all persisted downloads.
217 bool DownloadManager::Init(content::BrowserContext* browser_context) { 218 bool DownloadManagerImpl::Init(content::BrowserContext* browser_context) {
218 DCHECK(browser_context); 219 DCHECK(browser_context);
219 DCHECK(!shutdown_needed_) << "DownloadManager already initialized."; 220 DCHECK(!shutdown_needed_) << "DownloadManager already initialized.";
220 shutdown_needed_ = true; 221 shutdown_needed_ = true;
221 222
222 browser_context_ = browser_context; 223 browser_context_ = browser_context;
223 224
224 // In test mode, there may be no ResourceDispatcherHost. In this case it's 225 // In test mode, there may be no ResourceDispatcherHost. In this case it's
225 // safe to avoid setting |file_manager_| because we only call a small set of 226 // safe to avoid setting |file_manager_| because we only call a small set of
226 // functions, none of which need it. 227 // functions, none of which need it.
227 ResourceDispatcherHost* rdh = 228 ResourceDispatcherHost* rdh =
228 content::GetContentClient()->browser()->GetResourceDispatcherHost(); 229 content::GetContentClient()->browser()->GetResourceDispatcherHost();
229 if (rdh) { 230 if (rdh) {
230 file_manager_ = rdh->download_file_manager(); 231 file_manager_ = rdh->download_file_manager();
231 DCHECK(file_manager_); 232 DCHECK(file_manager_);
232 } 233 }
233 234
234 return true; 235 return true;
235 } 236 }
236 237
237 // We have received a message from DownloadFileManager about a new download. 238 // We have received a message from DownloadFileManager about a new download.
238 void DownloadManager::StartDownload(int32 download_id) { 239 void DownloadManagerImpl::StartDownload(int32 download_id) {
239 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 240 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
240 241
241 if (delegate_->ShouldStartDownload(download_id)) 242 if (delegate_->ShouldStartDownload(download_id))
242 RestartDownload(download_id); 243 RestartDownload(download_id);
243 } 244 }
244 245
245 void DownloadManager::CheckForHistoryFilesRemoval() { 246 void DownloadManagerImpl::CheckForHistoryFilesRemoval() {
246 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 247 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
247 for (DownloadMap::iterator it = history_downloads_.begin(); 248 for (DownloadMap::iterator it = history_downloads_.begin();
248 it != history_downloads_.end(); ++it) { 249 it != history_downloads_.end(); ++it) {
249 CheckForFileRemoval(it->second); 250 CheckForFileRemoval(it->second);
250 } 251 }
251 } 252 }
252 253
253 void DownloadManager::CheckForFileRemoval(DownloadItem* download_item) { 254 void DownloadManagerImpl::CheckForFileRemoval(DownloadItem* download_item) {
254 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 255 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
255 if (download_item->IsComplete() && 256 if (download_item->IsComplete() &&
256 !download_item->file_externally_removed()) { 257 !download_item->file_externally_removed()) {
257 BrowserThread::PostTask( 258 BrowserThread::PostTask(
258 BrowserThread::FILE, FROM_HERE, 259 BrowserThread::FILE, FROM_HERE,
259 base::Bind(&DownloadManager::CheckForFileRemovalOnFileThread, 260 base::Bind(&DownloadManagerImpl::CheckForFileRemovalOnFileThread,
260 this, download_item->db_handle(), 261 this, download_item->db_handle(),
261 download_item->GetTargetFilePath())); 262 download_item->GetTargetFilePath()));
262 } 263 }
263 } 264 }
264 265
265 void DownloadManager::CheckForFileRemovalOnFileThread( 266 void DownloadManagerImpl::CheckForFileRemovalOnFileThread(
266 int64 db_handle, const FilePath& path) { 267 int64 db_handle, const FilePath& path) {
267 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 268 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
268 if (!file_util::PathExists(path)) { 269 if (!file_util::PathExists(path)) {
269 BrowserThread::PostTask( 270 BrowserThread::PostTask(
270 BrowserThread::UI, FROM_HERE, 271 BrowserThread::UI, FROM_HERE,
271 base::Bind(&DownloadManager::OnFileRemovalDetected, this, db_handle)); 272 base::Bind(&DownloadManagerImpl::OnFileRemovalDetected,
273 this,
274 db_handle));
272 } 275 }
273 } 276 }
274 277
275 void DownloadManager::OnFileRemovalDetected(int64 db_handle) { 278 void DownloadManagerImpl::OnFileRemovalDetected(int64 db_handle) {
276 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 279 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
277 DownloadMap::iterator it = history_downloads_.find(db_handle); 280 DownloadMap::iterator it = history_downloads_.find(db_handle);
278 if (it != history_downloads_.end()) { 281 if (it != history_downloads_.end()) {
279 DownloadItem* download_item = it->second; 282 DownloadItem* download_item = it->second;
280 download_item->OnDownloadedFileRemoved(); 283 download_item->OnDownloadedFileRemoved();
281 } 284 }
282 } 285 }
283 286
284 void DownloadManager::RestartDownload( 287 void DownloadManagerImpl::RestartDownload(
285 int32 download_id) { 288 int32 download_id) {
286 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 289 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
287 290
288 DownloadItem* download = GetActiveDownloadItem(download_id); 291 DownloadItem* download = GetActiveDownloadItem(download_id);
289 if (!download) 292 if (!download)
290 return; 293 return;
291 294
292 VLOG(20) << __FUNCTION__ << "()" 295 VLOG(20) << __FUNCTION__ << "()"
293 << " download = " << download->DebugString(true); 296 << " download = " << download->DebugString(true);
294 297
(...skipping 12 matching lines...) Expand all
307 contents, suggested_path, reinterpret_cast<void*>(id_ptr)); 310 contents, suggested_path, reinterpret_cast<void*>(id_ptr));
308 311
309 FOR_EACH_OBSERVER(Observer, observers_, 312 FOR_EACH_OBSERVER(Observer, observers_,
310 SelectFileDialogDisplayed(download_id)); 313 SelectFileDialogDisplayed(download_id));
311 } else { 314 } else {
312 // No prompting for download, just continue with the suggested name. 315 // No prompting for download, just continue with the suggested name.
313 ContinueDownloadWithPath(download, suggested_path); 316 ContinueDownloadWithPath(download, suggested_path);
314 } 317 }
315 } 318 }
316 319
317 void DownloadManager::CreateDownloadItem( 320 content::BrowserContext* DownloadManagerImpl::BrowserContext() {
321 return browser_context_;
322 }
323
324 FilePath DownloadManagerImpl::LastDownloadPath() {
325 return last_download_path_;
326 }
327
328 void DownloadManagerImpl::CreateDownloadItem(
318 DownloadCreateInfo* info, const DownloadRequestHandle& request_handle) { 329 DownloadCreateInfo* info, const DownloadRequestHandle& request_handle) {
319 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 330 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
320 331
321 DownloadItem* download = new DownloadItem( 332 DownloadItem* download = new DownloadItem(
322 this, *info, new DownloadRequestHandle(request_handle), 333 this, *info, new DownloadRequestHandle(request_handle),
323 browser_context_->IsOffTheRecord()); 334 browser_context_->IsOffTheRecord());
324 int32 download_id = info->download_id.local(); 335 int32 download_id = info->download_id.local();
325 DCHECK(!ContainsKey(in_progress_, download_id)); 336 DCHECK(!ContainsKey(in_progress_, download_id));
326 337
327 // TODO(rdsmith): Remove after http://crbug.com/85408 resolved. 338 // TODO(rdsmith): Remove after http://crbug.com/85408 resolved.
328 CHECK(!ContainsKey(active_downloads_, download_id)); 339 CHECK(!ContainsKey(active_downloads_, download_id));
329 downloads_.insert(download); 340 downloads_.insert(download);
330 active_downloads_[download_id] = download; 341 active_downloads_[download_id] = download;
331 } 342 }
332 343
333 void DownloadManager::ContinueDownloadWithPath(DownloadItem* download, 344 void DownloadManagerImpl::ContinueDownloadWithPath(
334 const FilePath& chosen_file) { 345 DownloadItem* download, const FilePath& chosen_file) {
335 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 346 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
336 DCHECK(download); 347 DCHECK(download);
337 348
338 int32 download_id = download->id(); 349 int32 download_id = download->id();
339 350
340 // NOTE(ahendrickson) Eventually |active_downloads_| will replace 351 // NOTE(ahendrickson) Eventually |active_downloads_| will replace
341 // |in_progress_|, but we don't want to change the semantics yet. 352 // |in_progress_|, but we don't want to change the semantics yet.
342 DCHECK(!ContainsKey(in_progress_, download_id)); 353 DCHECK(!ContainsKey(in_progress_, download_id));
343 DCHECK(ContainsKey(downloads_, download)); 354 DCHECK(ContainsKey(downloads_, download));
344 DCHECK(ContainsKey(active_downloads_, download_id)); 355 DCHECK(ContainsKey(active_downloads_, download_id));
(...skipping 15 matching lines...) Expand all
360 BrowserThread::PostTask( 371 BrowserThread::PostTask(
361 BrowserThread::FILE, FROM_HERE, 372 BrowserThread::FILE, FROM_HERE,
362 base::Bind(&DownloadFileManager::RenameInProgressDownloadFile, 373 base::Bind(&DownloadFileManager::RenameInProgressDownloadFile,
363 file_manager_, download->global_id(), download_path)); 374 file_manager_, download->global_id(), download_path));
364 375
365 download->Rename(download_path); 376 download->Rename(download_path);
366 377
367 delegate_->AddItemToPersistentStore(download); 378 delegate_->AddItemToPersistentStore(download);
368 } 379 }
369 380
370 void DownloadManager::UpdateDownload(int32 download_id, int64 size) { 381 void DownloadManagerImpl::UpdateDownload(int32 download_id, int64 size) {
371 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 382 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
372 DownloadMap::iterator it = active_downloads_.find(download_id); 383 DownloadMap::iterator it = active_downloads_.find(download_id);
373 if (it != active_downloads_.end()) { 384 if (it != active_downloads_.end()) {
374 DownloadItem* download = it->second; 385 DownloadItem* download = it->second;
375 if (download->IsInProgress()) { 386 if (download->IsInProgress()) {
376 download->Update(size); 387 download->Update(size);
377 UpdateDownloadProgress(); // Reflect size updates. 388 UpdateDownloadProgress(); // Reflect size updates.
378 delegate_->UpdateItemInPersistentStore(download); 389 delegate_->UpdateItemInPersistentStore(download);
379 } 390 }
380 } 391 }
381 } 392 }
382 393
383 void DownloadManager::OnResponseCompleted(int32 download_id, 394 void DownloadManagerImpl::OnResponseCompleted(int32 download_id,
384 int64 size, 395 int64 size,
385 const std::string& hash) { 396 const std::string& hash) {
386 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 397 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
387 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id 398 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id
388 << " size = " << size; 399 << " size = " << size;
389 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 400 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
390 401
391 // If it's not in active_downloads_, that means it was cancelled; just 402 // If it's not in active_downloads_, that means it was cancelled; just
392 // ignore the notification. 403 // ignore the notification.
393 if (active_downloads_.count(download_id) == 0) 404 if (active_downloads_.count(download_id) == 0)
394 return; 405 return;
395 406
396 DownloadItem* download = active_downloads_[download_id]; 407 DownloadItem* download = active_downloads_[download_id];
397 download->OnAllDataSaved(size, hash); 408 download->OnAllDataSaved(size, hash);
398 delegate_->OnResponseCompleted(download); 409 delegate_->OnResponseCompleted(download);
399 410
400 MaybeCompleteDownload(download); 411 MaybeCompleteDownload(download);
401 } 412 }
402 413
403 void DownloadManager::AssertQueueStateConsistent(DownloadItem* download) { 414 void DownloadManagerImpl::AssertQueueStateConsistent(DownloadItem* download) {
404 // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. 415 // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved.
405 if (download->state() == DownloadItem::REMOVING) { 416 if (download->state() == DownloadItem::REMOVING) {
406 CHECK(!ContainsKey(downloads_, download)); 417 CHECK(!ContainsKey(downloads_, download));
407 CHECK(!ContainsKey(active_downloads_, download->id())); 418 CHECK(!ContainsKey(active_downloads_, download->id()));
408 CHECK(!ContainsKey(in_progress_, download->id())); 419 CHECK(!ContainsKey(in_progress_, download->id()));
409 CHECK(!ContainsKey(history_downloads_, download->db_handle())); 420 CHECK(!ContainsKey(history_downloads_, download->db_handle()));
410 return; 421 return;
411 } 422 }
412 423
413 // Should be in downloads_ if we're not REMOVING. 424 // Should be in downloads_ if we're not REMOVING.
(...skipping 16 matching lines...) Expand all
430 if (ContainsKey(active_downloads_, download->id())) { 441 if (ContainsKey(active_downloads_, download->id())) {
431 if (download->db_handle() != DownloadItem::kUninitializedHandle) 442 if (download->db_handle() != DownloadItem::kUninitializedHandle)
432 CHECK_EQ(DownloadItem::IN_PROGRESS, download->state()); 443 CHECK_EQ(DownloadItem::IN_PROGRESS, download->state());
433 if (DownloadItem::IN_PROGRESS != download->state()) 444 if (DownloadItem::IN_PROGRESS != download->state())
434 CHECK_EQ(DownloadItem::kUninitializedHandle, download->db_handle()); 445 CHECK_EQ(DownloadItem::kUninitializedHandle, download->db_handle());
435 } 446 }
436 if (DownloadItem::IN_PROGRESS == download->state()) 447 if (DownloadItem::IN_PROGRESS == download->state())
437 CHECK(ContainsKey(active_downloads_, download->id())); 448 CHECK(ContainsKey(active_downloads_, download->id()));
438 } 449 }
439 450
440 bool DownloadManager::IsDownloadReadyForCompletion(DownloadItem* download) { 451 bool DownloadManagerImpl::IsDownloadReadyForCompletion(DownloadItem* download) {
441 // If we don't have all the data, the download is not ready for 452 // If we don't have all the data, the download is not ready for
442 // completion. 453 // completion.
443 if (!download->all_data_saved()) 454 if (!download->all_data_saved())
444 return false; 455 return false;
445 456
446 // If the download is dangerous, but not yet validated, it's not ready for 457 // If the download is dangerous, but not yet validated, it's not ready for
447 // completion. 458 // completion.
448 if (download->safety_state() == DownloadItem::DANGEROUS) 459 if (download->safety_state() == DownloadItem::DANGEROUS)
449 return false; 460 return false;
450 461
451 // If the download isn't active (e.g. has been cancelled) it's not 462 // If the download isn't active (e.g. has been cancelled) it's not
452 // ready for completion. 463 // ready for completion.
453 if (active_downloads_.count(download->id()) == 0) 464 if (active_downloads_.count(download->id()) == 0)
454 return false; 465 return false;
455 466
456 // If the download hasn't been inserted into the history system 467 // If the download hasn't been inserted into the history system
457 // (which occurs strictly after file name determination, intermediate 468 // (which occurs strictly after file name determination, intermediate
458 // file rename, and UI display) then it's not ready for completion. 469 // file rename, and UI display) then it's not ready for completion.
459 if (download->db_handle() == DownloadItem::kUninitializedHandle) 470 if (download->db_handle() == DownloadItem::kUninitializedHandle)
460 return false; 471 return false;
461 472
462 return true; 473 return true;
463 } 474 }
464 475
465 void DownloadManager::MaybeCompleteDownload(DownloadItem* download) { 476 void DownloadManagerImpl::MaybeCompleteDownload(DownloadItem* download) {
466 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 477 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
467 VLOG(20) << __FUNCTION__ << "()" << " download = " 478 VLOG(20) << __FUNCTION__ << "()" << " download = "
468 << download->DebugString(false); 479 << download->DebugString(false);
469 480
470 if (!IsDownloadReadyForCompletion(download)) 481 if (!IsDownloadReadyForCompletion(download))
471 return; 482 return;
472 483
473 // TODO(rdsmith): DCHECK that we only pass through this point 484 // TODO(rdsmith): DCHECK that we only pass through this point
474 // once per download. The natural way to do this is by a state 485 // once per download. The natural way to do this is by a state
475 // transition on the DownloadItem. 486 // transition on the DownloadItem.
(...skipping 16 matching lines...) Expand all
492 // Remove the id from in_progress 503 // Remove the id from in_progress
493 in_progress_.erase(download->id()); 504 in_progress_.erase(download->id());
494 UpdateDownloadProgress(); // Reflect removal from in_progress_. 505 UpdateDownloadProgress(); // Reflect removal from in_progress_.
495 506
496 delegate_->UpdateItemInPersistentStore(download); 507 delegate_->UpdateItemInPersistentStore(download);
497 508
498 // Finish the download. 509 // Finish the download.
499 download->OnDownloadCompleting(file_manager_); 510 download->OnDownloadCompleting(file_manager_);
500 } 511 }
501 512
502 void DownloadManager::DownloadCompleted(int32 download_id) { 513 void DownloadManagerImpl::DownloadCompleted(int32 download_id) {
503 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 514 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
504 DownloadItem* download = GetDownloadItem(download_id); 515 DownloadItem* download = GetDownloadItem(download_id);
505 DCHECK(download); 516 DCHECK(download);
506 delegate_->UpdateItemInPersistentStore(download); 517 delegate_->UpdateItemInPersistentStore(download);
507 active_downloads_.erase(download_id); 518 active_downloads_.erase(download_id);
508 AssertQueueStateConsistent(download); 519 AssertQueueStateConsistent(download);
509 } 520 }
510 521
511 void DownloadManager::OnDownloadRenamedToFinalName(int download_id, 522 void DownloadManagerImpl::OnDownloadRenamedToFinalName(
512 const FilePath& full_path, 523 int download_id,
513 int uniquifier) { 524 const FilePath& full_path,
525 int uniquifier) {
514 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id 526 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id
515 << " full_path = \"" << full_path.value() << "\"" 527 << " full_path = \"" << full_path.value() << "\""
516 << " uniquifier = " << uniquifier; 528 << " uniquifier = " << uniquifier;
517 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 529 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
518 530
519 DownloadItem* item = GetDownloadItem(download_id); 531 DownloadItem* item = GetDownloadItem(download_id);
520 if (!item) 532 if (!item)
521 return; 533 return;
522 534
523 if (item->safety_state() == DownloadItem::SAFE) { 535 if (item->safety_state() == DownloadItem::SAFE) {
524 DCHECK_EQ(0, uniquifier) << "We should not uniquify SAFE downloads twice"; 536 DCHECK_EQ(0, uniquifier) << "We should not uniquify SAFE downloads twice";
525 } 537 }
526 538
527 BrowserThread::PostTask( 539 BrowserThread::PostTask(
528 BrowserThread::FILE, FROM_HERE, 540 BrowserThread::FILE, FROM_HERE,
529 base::Bind(&DownloadFileManager::CompleteDownload, 541 base::Bind(&DownloadFileManager::CompleteDownload,
530 file_manager_, item->global_id())); 542 file_manager_, item->global_id()));
531 543
532 if (uniquifier) 544 if (uniquifier)
533 item->set_path_uniquifier(uniquifier); 545 item->set_path_uniquifier(uniquifier);
534 546
535 item->OnDownloadRenamedToFinalName(full_path); 547 item->OnDownloadRenamedToFinalName(full_path);
536 delegate_->UpdatePathForItemInPersistentStore(item, full_path); 548 delegate_->UpdatePathForItemInPersistentStore(item, full_path);
537 } 549 }
538 550
539 void DownloadManager::CancelDownload(int32 download_id) { 551 void DownloadManagerImpl::CancelDownload(int32 download_id) {
540 DownloadItem* download = GetActiveDownload(download_id); 552 DownloadItem* download = GetActiveDownload(download_id);
541 // A cancel at the right time could remove the download from the 553 // A cancel at the right time could remove the download from the
542 // |active_downloads_| map before we get here. 554 // |active_downloads_| map before we get here.
543 if (!download) 555 if (!download)
544 return; 556 return;
545 557
546 download->Cancel(true); 558 download->Cancel(true);
547 } 559 }
548 560
549 void DownloadManager::DownloadCancelledInternal(DownloadItem* download) { 561 void DownloadManagerImpl::DownloadCancelledInternal(DownloadItem* download) {
550 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 562 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
551 563
552 VLOG(20) << __FUNCTION__ << "()" 564 VLOG(20) << __FUNCTION__ << "()"
553 << " download = " << download->DebugString(true); 565 << " download = " << download->DebugString(true);
554 566
555 RemoveFromActiveList(download); 567 RemoveFromActiveList(download);
556 // This function is called from the DownloadItem, so DI state 568 // This function is called from the DownloadItem, so DI state
557 // should already have been updated. 569 // should already have been updated.
558 AssertQueueStateConsistent(download); 570 AssertQueueStateConsistent(download);
559 571
560 if (file_manager_) 572 if (file_manager_)
561 download->OffThreadCancel(file_manager_); 573 download->OffThreadCancel(file_manager_);
562 } 574 }
563 575
564 void DownloadManager::OnDownloadInterrupted(int32 download_id, 576 void DownloadManagerImpl::OnDownloadInterrupted(int32 download_id,
565 int64 size, 577 int64 size,
566 InterruptReason reason) { 578 InterruptReason reason) {
567 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 579 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
568 580
569 DownloadItem* download = GetActiveDownload(download_id); 581 DownloadItem* download = GetActiveDownload(download_id);
570 if (!download) 582 if (!download)
571 return; 583 return;
572 584
573 VLOG(20) << __FUNCTION__ << "()" 585 VLOG(20) << __FUNCTION__ << "()"
574 << " reason " << InterruptReasonDebugString(reason) 586 << " reason " << InterruptReasonDebugString(reason)
575 << " at offset " << download->received_bytes() 587 << " at offset " << download->received_bytes()
576 << " size = " << size 588 << " size = " << size
577 << " download = " << download->DebugString(true); 589 << " download = " << download->DebugString(true);
578 590
579 RemoveFromActiveList(download); 591 RemoveFromActiveList(download);
580 download->Interrupted(size, reason); 592 download->Interrupted(size, reason);
581 download->OffThreadCancel(file_manager_); 593 download->OffThreadCancel(file_manager_);
582 } 594 }
583 595
584 DownloadItem* DownloadManager::GetActiveDownload(int32 download_id) { 596 DownloadItem* DownloadManagerImpl::GetActiveDownload(int32 download_id) {
585 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 597 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
586 DownloadMap::iterator it = active_downloads_.find(download_id); 598 DownloadMap::iterator it = active_downloads_.find(download_id);
587 if (it == active_downloads_.end()) 599 if (it == active_downloads_.end())
588 return NULL; 600 return NULL;
589 601
590 DownloadItem* download = it->second; 602 DownloadItem* download = it->second;
591 603
592 DCHECK(download); 604 DCHECK(download);
593 DCHECK_EQ(download_id, download->id()); 605 DCHECK_EQ(download_id, download->id());
594 606
595 return download; 607 return download;
596 } 608 }
597 609
598 void DownloadManager::RemoveFromActiveList(DownloadItem* download) { 610 void DownloadManagerImpl::RemoveFromActiveList(DownloadItem* download) {
599 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 611 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
600 DCHECK(download); 612 DCHECK(download);
601 613
602 // Clean up will happen when the history system create callback runs if we 614 // Clean up will happen when the history system create callback runs if we
603 // don't have a valid db_handle yet. 615 // don't have a valid db_handle yet.
604 if (download->db_handle() != DownloadItem::kUninitializedHandle) { 616 if (download->db_handle() != DownloadItem::kUninitializedHandle) {
605 in_progress_.erase(download->id()); 617 in_progress_.erase(download->id());
606 active_downloads_.erase(download->id()); 618 active_downloads_.erase(download->id());
607 UpdateDownloadProgress(); // Reflect removal from in_progress_. 619 UpdateDownloadProgress(); // Reflect removal from in_progress_.
608 delegate_->UpdateItemInPersistentStore(download); 620 delegate_->UpdateItemInPersistentStore(download);
609 } 621 }
610 } 622 }
611 623
612 void DownloadManager::SetDownloadManagerDelegate( 624 content::DownloadManagerDelegate* DownloadManagerImpl::delegate() const {
625 return delegate_;
626 }
627
628 void DownloadManagerImpl::SetDownloadManagerDelegate(
613 content::DownloadManagerDelegate* delegate) { 629 content::DownloadManagerDelegate* delegate) {
614 delegate_ = delegate; 630 delegate_ = delegate;
615 } 631 }
616 632
617 void DownloadManager::UpdateDownloadProgress() { 633 void DownloadManagerImpl::UpdateDownloadProgress() {
618 delegate_->DownloadProgressUpdated(); 634 delegate_->DownloadProgressUpdated();
619 } 635 }
620 636
621 int DownloadManager::RemoveDownloadItems( 637 int DownloadManagerImpl::RemoveDownloadItems(
622 const DownloadVector& pending_deletes) { 638 const DownloadVector& pending_deletes) {
623 if (pending_deletes.empty()) 639 if (pending_deletes.empty())
624 return 0; 640 return 0;
625 641
626 // Delete from internal maps. 642 // Delete from internal maps.
627 for (DownloadVector::const_iterator it = pending_deletes.begin(); 643 for (DownloadVector::const_iterator it = pending_deletes.begin();
628 it != pending_deletes.end(); 644 it != pending_deletes.end();
629 ++it) { 645 ++it) {
630 DownloadItem* download = *it; 646 DownloadItem* download = *it;
631 DCHECK(download); 647 DCHECK(download);
632 history_downloads_.erase(download->db_handle()); 648 history_downloads_.erase(download->db_handle());
633 save_page_downloads_.erase(download->id()); 649 save_page_downloads_.erase(download->id());
634 downloads_.erase(download); 650 downloads_.erase(download);
635 } 651 }
636 652
637 // Tell observers to refresh their views. 653 // Tell observers to refresh their views.
638 NotifyModelChanged(); 654 NotifyModelChanged();
639 655
640 // Delete the download items themselves. 656 // Delete the download items themselves.
641 const int num_deleted = static_cast<int>(pending_deletes.size()); 657 const int num_deleted = static_cast<int>(pending_deletes.size());
642 STLDeleteContainerPointers(pending_deletes.begin(), pending_deletes.end()); 658 STLDeleteContainerPointers(pending_deletes.begin(), pending_deletes.end());
643 return num_deleted; 659 return num_deleted;
644 } 660 }
645 661
646 void DownloadManager::RemoveDownload(int64 download_handle) { 662 void DownloadManagerImpl::RemoveDownload(int64 download_handle) {
647 DownloadMap::iterator it = history_downloads_.find(download_handle); 663 DownloadMap::iterator it = history_downloads_.find(download_handle);
648 if (it == history_downloads_.end()) 664 if (it == history_downloads_.end())
649 return; 665 return;
650 666
651 // Make history update. 667 // Make history update.
652 DownloadItem* download = it->second; 668 DownloadItem* download = it->second;
653 delegate_->RemoveItemFromPersistentStore(download); 669 delegate_->RemoveItemFromPersistentStore(download);
654 670
655 // Remove from our tables and delete. 671 // Remove from our tables and delete.
656 int downloads_count = RemoveDownloadItems(DownloadVector(1, download)); 672 int downloads_count = RemoveDownloadItems(DownloadVector(1, download));
657 DCHECK_EQ(1, downloads_count); 673 DCHECK_EQ(1, downloads_count);
658 } 674 }
659 675
660 int DownloadManager::RemoveDownloadsBetween(const base::Time remove_begin, 676 int DownloadManagerImpl::RemoveDownloadsBetween(const base::Time remove_begin,
661 const base::Time remove_end) { 677 const base::Time remove_end) {
662 delegate_->RemoveItemsFromPersistentStoreBetween(remove_begin, remove_end); 678 delegate_->RemoveItemsFromPersistentStoreBetween(remove_begin, remove_end);
663 679
664 // All downloads visible to the user will be in the history, 680 // All downloads visible to the user will be in the history,
665 // so scan that map. 681 // so scan that map.
666 DownloadVector pending_deletes; 682 DownloadVector pending_deletes;
667 for (DownloadMap::const_iterator it = history_downloads_.begin(); 683 for (DownloadMap::const_iterator it = history_downloads_.begin();
668 it != history_downloads_.end(); 684 it != history_downloads_.end();
669 ++it) { 685 ++it) {
670 DownloadItem* download = it->second; 686 DownloadItem* download = it->second;
671 if (download->start_time() >= remove_begin && 687 if (download->start_time() >= remove_begin &&
672 (remove_end.is_null() || download->start_time() < remove_end) && 688 (remove_end.is_null() || download->start_time() < remove_end) &&
673 (download->IsComplete() || download->IsCancelled())) { 689 (download->IsComplete() || download->IsCancelled())) {
674 AssertQueueStateConsistent(download); 690 AssertQueueStateConsistent(download);
675 pending_deletes.push_back(download); 691 pending_deletes.push_back(download);
676 } 692 }
677 } 693 }
678 return RemoveDownloadItems(pending_deletes); 694 return RemoveDownloadItems(pending_deletes);
679 } 695 }
680 696
681 int DownloadManager::RemoveDownloads(const base::Time remove_begin) { 697 int DownloadManagerImpl::RemoveDownloads(const base::Time remove_begin) {
682 return RemoveDownloadsBetween(remove_begin, base::Time()); 698 return RemoveDownloadsBetween(remove_begin, base::Time());
683 } 699 }
684 700
685 int DownloadManager::RemoveAllDownloads() { 701 int DownloadManagerImpl::RemoveAllDownloads() {
686 download_stats::RecordClearAllSize(history_downloads_.size()); 702 download_stats::RecordClearAllSize(history_downloads_.size());
687 // The null times make the date range unbounded. 703 // The null times make the date range unbounded.
688 return RemoveDownloadsBetween(base::Time(), base::Time()); 704 return RemoveDownloadsBetween(base::Time(), base::Time());
689 } 705 }
690 706
691 // Initiate a download of a specific URL. We send the request to the 707 // Initiate a download of a specific URL. We send the request to the
692 // ResourceDispatcherHost, and let it send us responses like a regular 708 // ResourceDispatcherHost, and let it send us responses like a regular
693 // download. 709 // download.
694 void DownloadManager::DownloadUrl(const GURL& url, 710 void DownloadManagerImpl::DownloadUrl(const GURL& url,
695 const GURL& referrer, 711 const GURL& referrer,
696 const std::string& referrer_charset, 712 const std::string& referrer_charset,
697 TabContents* tab_contents) { 713 TabContents* tab_contents) {
698 DownloadUrlToFile(url, referrer, referrer_charset, DownloadSaveInfo(), 714 DownloadUrlToFile(url, referrer, referrer_charset, DownloadSaveInfo(),
699 tab_contents); 715 tab_contents);
700 } 716 }
701 717
702 void DownloadManager::DownloadUrlToFile(const GURL& url, 718 void DownloadManagerImpl::DownloadUrlToFile(const GURL& url,
703 const GURL& referrer, 719 const GURL& referrer,
704 const std::string& referrer_charset, 720 const std::string& referrer_charset,
705 const DownloadSaveInfo& save_info, 721 const DownloadSaveInfo& save_info,
706 TabContents* tab_contents) { 722 TabContents* tab_contents) {
707 DCHECK(tab_contents); 723 DCHECK(tab_contents);
708 ResourceDispatcherHost* resource_dispatcher_host = 724 ResourceDispatcherHost* resource_dispatcher_host =
709 content::GetContentClient()->browser()->GetResourceDispatcherHost(); 725 content::GetContentClient()->browser()->GetResourceDispatcherHost();
710 // We send a pointer to content::ResourceContext, instead of the usual 726 // We send a pointer to content::ResourceContext, instead of the usual
711 // reference, so that a copy of the object isn't made. 727 // reference, so that a copy of the object isn't made.
712 // base::Bind can't handle 7 args, so we use URLParams and RenderParams. 728 // base::Bind can't handle 7 args, so we use URLParams and RenderParams.
713 BrowserThread::PostTask( 729 BrowserThread::PostTask(
714 BrowserThread::IO, FROM_HERE, 730 BrowserThread::IO, FROM_HERE,
715 base::Bind(&BeginDownload, 731 base::Bind(&BeginDownload,
716 URLParams(url, referrer), save_info, resource_dispatcher_host, 732 URLParams(url, referrer), save_info, resource_dispatcher_host,
717 RenderParams(tab_contents->GetRenderProcessHost()->id(), 733 RenderParams(tab_contents->GetRenderProcessHost()->id(),
718 tab_contents->render_view_host()->routing_id()), 734 tab_contents->render_view_host()->routing_id()),
719 &tab_contents->browser_context()->GetResourceContext())); 735 &tab_contents->browser_context()->GetResourceContext()));
720 } 736 }
721 737
722 void DownloadManager::AddObserver(Observer* observer) { 738 void DownloadManagerImpl::AddObserver(Observer* observer) {
723 observers_.AddObserver(observer); 739 observers_.AddObserver(observer);
724 observer->ModelChanged(); 740 observer->ModelChanged();
725 } 741 }
726 742
727 void DownloadManager::RemoveObserver(Observer* observer) { 743 void DownloadManagerImpl::RemoveObserver(Observer* observer) {
728 observers_.RemoveObserver(observer); 744 observers_.RemoveObserver(observer);
729 } 745 }
730 746
731 bool DownloadManager::IsDownloadProgressKnown() const { 747 bool DownloadManagerImpl::IsDownloadProgressKnown() const {
732 for (DownloadMap::const_iterator i = in_progress_.begin(); 748 for (DownloadMap::const_iterator i = in_progress_.begin();
733 i != in_progress_.end(); ++i) { 749 i != in_progress_.end(); ++i) {
734 if (i->second->total_bytes() <= 0) 750 if (i->second->total_bytes() <= 0)
735 return false; 751 return false;
736 } 752 }
737 753
738 return true; 754 return true;
739 } 755 }
740 756
741 int64 DownloadManager::GetInProgressDownloadCount() const { 757 int64 DownloadManagerImpl::GetInProgressDownloadCount() const {
742 return in_progress_.size(); 758 return in_progress_.size();
743 } 759 }
744 760
745 int64 DownloadManager::GetReceivedDownloadBytes() const { 761 int64 DownloadManagerImpl::GetReceivedDownloadBytes() const {
746 DCHECK(IsDownloadProgressKnown()); 762 DCHECK(IsDownloadProgressKnown());
747 int64 received_bytes = 0; 763 int64 received_bytes = 0;
748 for (DownloadMap::const_iterator i = in_progress_.begin(); 764 for (DownloadMap::const_iterator i = in_progress_.begin();
749 i != in_progress_.end(); ++i) { 765 i != in_progress_.end(); ++i) {
750 received_bytes += i->second->received_bytes(); 766 received_bytes += i->second->received_bytes();
751 } 767 }
752 return received_bytes; 768 return received_bytes;
753 } 769 }
754 770
755 int64 DownloadManager::GetTotalDownloadBytes() const { 771 int64 DownloadManagerImpl::GetTotalDownloadBytes() const {
756 DCHECK(IsDownloadProgressKnown()); 772 DCHECK(IsDownloadProgressKnown());
757 int64 total_bytes = 0; 773 int64 total_bytes = 0;
758 for (DownloadMap::const_iterator i = in_progress_.begin(); 774 for (DownloadMap::const_iterator i = in_progress_.begin();
759 i != in_progress_.end(); ++i) { 775 i != in_progress_.end(); ++i) {
760 total_bytes += i->second->total_bytes(); 776 total_bytes += i->second->total_bytes();
761 } 777 }
762 return total_bytes; 778 return total_bytes;
763 } 779 }
764 780
765 void DownloadManager::FileSelected(const FilePath& path, void* params) { 781 void DownloadManagerImpl::FileSelected(const FilePath& path, void* params) {
766 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 782 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
767 783
768 int32* id_ptr = reinterpret_cast<int32*>(params); 784 int32* id_ptr = reinterpret_cast<int32*>(params);
769 DCHECK(id_ptr != NULL); 785 DCHECK(id_ptr != NULL);
770 int32 download_id = *id_ptr; 786 int32 download_id = *id_ptr;
771 delete id_ptr; 787 delete id_ptr;
772 788
773 DownloadItem* download = GetActiveDownloadItem(download_id); 789 DownloadItem* download = GetActiveDownloadItem(download_id);
774 if (!download) 790 if (!download)
775 return; 791 return;
776 VLOG(20) << __FUNCTION__ << "()" << " path = \"" << path.value() << "\"" 792 VLOG(20) << __FUNCTION__ << "()" << " path = \"" << path.value() << "\""
777 << " download = " << download->DebugString(true); 793 << " download = " << download->DebugString(true);
778 794
779 if (download->prompt_user_for_save_location()) 795 if (download->prompt_user_for_save_location())
780 last_download_path_ = path.DirName(); 796 last_download_path_ = path.DirName();
781 797
782 // Make sure the initial file name is set only once. 798 // Make sure the initial file name is set only once.
783 ContinueDownloadWithPath(download, path); 799 ContinueDownloadWithPath(download, path);
784 } 800 }
785 801
786 void DownloadManager::FileSelectionCanceled(void* params) { 802 void DownloadManagerImpl::FileSelectionCanceled(void* params) {
787 // The user didn't pick a place to save the file, so need to cancel the 803 // The user didn't pick a place to save the file, so need to cancel the
788 // download that's already in progress to the temporary location. 804 // download that's already in progress to the temporary location.
789 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 805 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
790 int32* id_ptr = reinterpret_cast<int32*>(params); 806 int32* id_ptr = reinterpret_cast<int32*>(params);
791 DCHECK(id_ptr != NULL); 807 DCHECK(id_ptr != NULL);
792 int32 download_id = *id_ptr; 808 int32 download_id = *id_ptr;
793 delete id_ptr; 809 delete id_ptr;
794 810
795 DownloadItem* download = GetActiveDownloadItem(download_id); 811 DownloadItem* download = GetActiveDownloadItem(download_id);
796 if (!download) 812 if (!download)
797 return; 813 return;
798 814
799 VLOG(20) << __FUNCTION__ << "()" 815 VLOG(20) << __FUNCTION__ << "()"
800 << " download = " << download->DebugString(true); 816 << " download = " << download->DebugString(true);
801 817
802 // TODO(ahendrickson) -- This currently has no effect, as the download is 818 // TODO(ahendrickson) -- This currently has no effect, as the download is
803 // not put on the active list until the file selection is complete. Need 819 // not put on the active list until the file selection is complete. Need
804 // to put it on the active list earlier in the process. 820 // to put it on the active list earlier in the process.
805 RemoveFromActiveList(download); 821 RemoveFromActiveList(download);
806 822
807 download->OffThreadCancel(file_manager_); 823 download->OffThreadCancel(file_manager_);
808 } 824 }
809 825
810 // Operations posted to us from the history service ---------------------------- 826 // Operations posted to us from the history service ----------------------------
811 827
812 // The history service has retrieved all download entries. 'entries' contains 828 // The history service has retrieved all download entries. 'entries' contains
813 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time). 829 // 'DownloadPersistentStoreInfo's in sorted order (by ascending start_time).
814 void DownloadManager::OnPersistentStoreQueryComplete( 830 void DownloadManagerImpl::OnPersistentStoreQueryComplete(
815 std::vector<DownloadPersistentStoreInfo>* entries) { 831 std::vector<DownloadPersistentStoreInfo>* entries) {
816 // TODO(rdsmith): Remove this and related logic when 832 // TODO(rdsmith): Remove this and related logic when
817 // http://crbug.com/85408 is fixed. 833 // http://crbug.com/85408 is fixed.
818 largest_db_handle_in_history_ = 0; 834 largest_db_handle_in_history_ = 0;
819 835
820 for (size_t i = 0; i < entries->size(); ++i) { 836 for (size_t i = 0; i < entries->size(); ++i) {
821 DownloadItem* download = new DownloadItem(this, entries->at(i)); 837 DownloadItem* download = new DownloadItem(this, entries->at(i));
822 // TODO(rdsmith): Remove after http://crbug.com/85408 resolved. 838 // TODO(rdsmith): Remove after http://crbug.com/85408 resolved.
823 CHECK(!ContainsKey(history_downloads_, download->db_handle())); 839 CHECK(!ContainsKey(history_downloads_, download->db_handle()));
824 downloads_.insert(download); 840 downloads_.insert(download);
825 history_downloads_[download->db_handle()] = download; 841 history_downloads_[download->db_handle()] = download;
826 VLOG(20) << __FUNCTION__ << "()" << i << ">" 842 VLOG(20) << __FUNCTION__ << "()" << i << ">"
827 << " download = " << download->DebugString(true); 843 << " download = " << download->DebugString(true);
828 844
829 if (download->db_handle() > largest_db_handle_in_history_) 845 if (download->db_handle() > largest_db_handle_in_history_)
830 largest_db_handle_in_history_ = download->db_handle(); 846 largest_db_handle_in_history_ = download->db_handle();
831 } 847 }
832 NotifyModelChanged(); 848 NotifyModelChanged();
833 CheckForHistoryFilesRemoval(); 849 CheckForHistoryFilesRemoval();
834 } 850 }
835 851
836 void DownloadManager::AddDownloadItemToHistory(DownloadItem* download, 852 void DownloadManagerImpl::AddDownloadItemToHistory(DownloadItem* download,
837 int64 db_handle) { 853 int64 db_handle) {
838 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 854 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
839 855
840 // TODO(rdsmith): Convert to DCHECK() when http://crbug.com/85408 856 // TODO(rdsmith): Convert to DCHECK() when http://crbug.com/85408
841 // is fixed. 857 // is fixed.
842 CHECK_NE(DownloadItem::kUninitializedHandle, db_handle); 858 CHECK_NE(DownloadItem::kUninitializedHandle, db_handle);
843 859
844 download_stats::RecordHistorySize(history_downloads_.size()); 860 download_stats::RecordHistorySize(history_downloads_.size());
845 861
846 DCHECK(download->db_handle() == DownloadItem::kUninitializedHandle); 862 DCHECK(download->db_handle() == DownloadItem::kUninitializedHandle);
847 download->set_db_handle(db_handle); 863 download->set_db_handle(db_handle);
848 864
849 // TODO(rdsmith): Convert to DCHECK() when http://crbug.com/85408 865 // TODO(rdsmith): Convert to DCHECK() when http://crbug.com/85408
850 // is fixed. 866 // is fixed.
851 CHECK(!ContainsKey(history_downloads_, download->db_handle())); 867 CHECK(!ContainsKey(history_downloads_, download->db_handle()));
852 history_downloads_[download->db_handle()] = download; 868 history_downloads_[download->db_handle()] = download;
853 869
854 // Show in the appropriate browser UI. 870 // Show in the appropriate browser UI.
855 // This includes buttons to save or cancel, for a dangerous download. 871 // This includes buttons to save or cancel, for a dangerous download.
856 ShowDownloadInBrowser(download); 872 ShowDownloadInBrowser(download);
857 873
858 // Inform interested objects about the new download. 874 // Inform interested objects about the new download.
859 NotifyModelChanged(); 875 NotifyModelChanged();
860 } 876 }
861 877
862 878
863 void DownloadManager::OnItemAddedToPersistentStore(int32 download_id, 879 void DownloadManagerImpl::OnItemAddedToPersistentStore(int32 download_id,
864 int64 db_handle) { 880 int64 db_handle) {
865 if (save_page_downloads_.count(download_id)) { 881 if (save_page_downloads_.count(download_id)) {
866 OnSavePageItemAddedToPersistentStore(download_id, db_handle); 882 OnSavePageItemAddedToPersistentStore(download_id, db_handle);
867 } else if (active_downloads_.count(download_id)) { 883 } else if (active_downloads_.count(download_id)) {
868 OnDownloadItemAddedToPersistentStore(download_id, db_handle); 884 OnDownloadItemAddedToPersistentStore(download_id, db_handle);
869 } 885 }
870 // It's valid that we don't find a matching item, i.e. on shutdown. 886 // It's valid that we don't find a matching item, i.e. on shutdown.
871 } 887 }
872 888
873 // Once the new DownloadItem's creation info has been committed to the history 889 // Once the new DownloadItem's creation info has been committed to the history
874 // service, we associate the DownloadItem with the db handle, update our 890 // service, we associate the DownloadItem with the db handle, update our
875 // 'history_downloads_' map and inform observers. 891 // 'history_downloads_' map and inform observers.
876 void DownloadManager::OnDownloadItemAddedToPersistentStore(int32 download_id, 892 void DownloadManagerImpl::OnDownloadItemAddedToPersistentStore(
877 int64 db_handle) { 893 int32 download_id, int64 db_handle) {
878 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 894 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
879 DownloadItem* download = GetActiveDownloadItem(download_id); 895 DownloadItem* download = GetActiveDownloadItem(download_id);
880 if (!download) 896 if (!download)
881 return; 897 return;
882 898
883 VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << db_handle 899 VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << db_handle
884 << " download_id = " << download_id 900 << " download_id = " << download_id
885 << " download = " << download->DebugString(true); 901 << " download = " << download->DebugString(true);
886 902
887 // TODO(rdsmith): Remove after http://crbug.com/85408 resolved. 903 // TODO(rdsmith): Remove after http://crbug.com/85408 resolved.
(...skipping 22 matching lines...) Expand all
910 // is fixed. 926 // is fixed.
911 CHECK(download->IsCancelled()) 927 CHECK(download->IsCancelled())
912 << " download = " << download->DebugString(true); 928 << " download = " << download->DebugString(true);
913 in_progress_.erase(download_id); 929 in_progress_.erase(download_id);
914 active_downloads_.erase(download_id); 930 active_downloads_.erase(download_id);
915 delegate_->UpdateItemInPersistentStore(download); 931 delegate_->UpdateItemInPersistentStore(download);
916 download->UpdateObservers(); 932 download->UpdateObservers();
917 } 933 }
918 } 934 }
919 935
920 void DownloadManager::ShowDownloadInBrowser(DownloadItem* download) { 936 void DownloadManagerImpl::ShowDownloadInBrowser(DownloadItem* download) {
921 // The 'contents' may no longer exist if the user closed the tab before we 937 // The 'contents' may no longer exist if the user closed the tab before we
922 // get this start completion event. 938 // get this start completion event.
923 TabContents* content = download->GetTabContents(); 939 TabContents* content = download->GetTabContents();
924 940
925 // If the contents no longer exists, we ask the embedder to suggest another 941 // If the contents no longer exists, we ask the embedder to suggest another
926 // tab. 942 // tab.
927 if (!content) 943 if (!content)
928 content = delegate_->GetAlternativeTabContentsToNotifyForDownload(); 944 content = delegate_->GetAlternativeTabContentsToNotifyForDownload();
929 945
930 if (content) 946 if (content)
931 content->OnStartDownload(download); 947 content->OnStartDownload(download);
932 } 948 }
933 949
950 int DownloadManagerImpl::InProgressCount() const {
951 return static_cast<int>(in_progress_.size());
952 }
953
934 // Clears the last download path, used to initialize "save as" dialogs. 954 // Clears the last download path, used to initialize "save as" dialogs.
935 void DownloadManager::ClearLastDownloadPath() { 955 void DownloadManagerImpl::ClearLastDownloadPath() {
936 last_download_path_ = FilePath(); 956 last_download_path_ = FilePath();
937 } 957 }
938 958
939 void DownloadManager::NotifyModelChanged() { 959 void DownloadManagerImpl::NotifyModelChanged() {
940 FOR_EACH_OBSERVER(Observer, observers_, ModelChanged()); 960 FOR_EACH_OBSERVER(Observer, observers_, ModelChanged());
941 } 961 }
942 962
943 DownloadItem* DownloadManager::GetDownloadItem(int download_id) { 963 DownloadItem* DownloadManagerImpl::GetDownloadItem(int download_id) {
944 // The |history_downloads_| map is indexed by the download's db_handle, 964 // The |history_downloads_| map is indexed by the download's db_handle,
945 // not its id, so we have to iterate. 965 // not its id, so we have to iterate.
946 for (DownloadMap::iterator it = history_downloads_.begin(); 966 for (DownloadMap::iterator it = history_downloads_.begin();
947 it != history_downloads_.end(); ++it) { 967 it != history_downloads_.end(); ++it) {
948 DownloadItem* item = it->second; 968 DownloadItem* item = it->second;
949 if (item->id() == download_id) 969 if (item->id() == download_id)
950 return item; 970 return item;
951 } 971 }
952 return NULL; 972 return NULL;
953 } 973 }
954 974
955 DownloadItem* DownloadManager::GetActiveDownloadItem(int download_id) { 975 DownloadItem* DownloadManagerImpl::GetActiveDownloadItem(int download_id) {
956 DCHECK(ContainsKey(active_downloads_, download_id)); 976 DCHECK(ContainsKey(active_downloads_, download_id));
957 DownloadItem* download = active_downloads_[download_id]; 977 DownloadItem* download = active_downloads_[download_id];
958 DCHECK(download != NULL); 978 DCHECK(download != NULL);
959 return download; 979 return download;
960 } 980 }
961 981
962 // Confirm that everything in all maps is also in |downloads_|, and that 982 // Confirm that everything in all maps is also in |downloads_|, and that
963 // everything in |downloads_| is also in some other map. 983 // everything in |downloads_| is also in some other map.
964 void DownloadManager::AssertContainersConsistent() const { 984 void DownloadManagerImpl::AssertContainersConsistent() const {
965 #if !defined(NDEBUG) 985 #if !defined(NDEBUG)
966 // Turn everything into sets. 986 // Turn everything into sets.
967 const DownloadMap* input_maps[] = {&active_downloads_, 987 const DownloadMap* input_maps[] = {&active_downloads_,
968 &history_downloads_, 988 &history_downloads_,
969 &save_page_downloads_}; 989 &save_page_downloads_};
970 DownloadSet active_set, history_set, save_page_set; 990 DownloadSet active_set, history_set, save_page_set;
971 DownloadSet* all_sets[] = {&active_set, &history_set, &save_page_set}; 991 DownloadSet* all_sets[] = {&active_set, &history_set, &save_page_set};
972 DCHECK_EQ(ARRAYSIZE_UNSAFE(input_maps), ARRAYSIZE_UNSAFE(all_sets)); 992 DCHECK_EQ(ARRAYSIZE_UNSAFE(input_maps), ARRAYSIZE_UNSAFE(all_sets));
973 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(input_maps); i++) { 993 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(input_maps); i++) {
974 for (DownloadMap::const_iterator it = input_maps[i]->begin(); 994 for (DownloadMap::const_iterator it = input_maps[i]->begin();
(...skipping 22 matching lines...) Expand all
997 DownloadSet remainder; 1017 DownloadSet remainder;
998 std::insert_iterator<DownloadSet> 1018 std::insert_iterator<DownloadSet>
999 insert_remainder(remainder, remainder.begin()); 1019 insert_remainder(remainder, remainder.begin());
1000 std::set_difference(downloads_.begin(), downloads_.end(), 1020 std::set_difference(downloads_.begin(), downloads_.end(),
1001 downloads_union.begin(), downloads_union.end(), 1021 downloads_union.begin(), downloads_union.end(),
1002 insert_remainder); 1022 insert_remainder);
1003 DCHECK(remainder.empty()); 1023 DCHECK(remainder.empty());
1004 #endif 1024 #endif
1005 } 1025 }
1006 1026
1007 void DownloadManager::SavePageDownloadStarted(DownloadItem* download) { 1027 void DownloadManagerImpl::SavePageDownloadStarted(DownloadItem* download) {
1008 DCHECK(!ContainsKey(save_page_downloads_, download->id())); 1028 DCHECK(!ContainsKey(save_page_downloads_, download->id()));
1009 downloads_.insert(download); 1029 downloads_.insert(download);
1010 save_page_downloads_[download->id()] = download; 1030 save_page_downloads_[download->id()] = download;
1011 1031
1012 // Add this entry to the history service. 1032 // Add this entry to the history service.
1013 // Additionally, the UI is notified in the callback. 1033 // Additionally, the UI is notified in the callback.
1014 delegate_->AddItemToPersistentStore(download); 1034 delegate_->AddItemToPersistentStore(download);
1015 } 1035 }
1016 1036
1017 // SavePackage will call SavePageDownloadFinished upon completion/cancellation. 1037 // SavePackage will call SavePageDownloadFinished upon completion/cancellation.
1018 // The history callback will call OnSavePageItemAddedToPersistentStore. 1038 // The history callback will call OnSavePageItemAddedToPersistentStore.
1019 // If the download finishes before the history callback, 1039 // If the download finishes before the history callback,
1020 // OnSavePageItemAddedToPersistentStore calls SavePageDownloadFinished, ensuring 1040 // OnSavePageItemAddedToPersistentStore calls SavePageDownloadFinished, ensuring
1021 // that the history event is update regardless of the order in which these two 1041 // that the history event is update regardless of the order in which these two
1022 // events complete. 1042 // events complete.
1023 // If something removes the download item from the download manager (Remove, 1043 // If something removes the download item from the download manager (Remove,
1024 // Shutdown) the result will be that the SavePage system will not be able to 1044 // Shutdown) the result will be that the SavePage system will not be able to
1025 // properly update the download item (which no longer exists) or the download 1045 // properly update the download item (which no longer exists) or the download
1026 // history, but the action will complete properly anyway. This may lead to the 1046 // history, but the action will complete properly anyway. This may lead to the
1027 // history entry being wrong on a reload of chrome (specifically in the case of 1047 // history entry being wrong on a reload of chrome (specifically in the case of
1028 // Initiation -> History Callback -> Removal -> Completion), but there's no way 1048 // Initiation -> History Callback -> Removal -> Completion), but there's no way
1029 // to solve that without canceling on Remove (which would then update the DB). 1049 // to solve that without canceling on Remove (which would then update the DB).
1030 1050
1031 void DownloadManager::OnSavePageItemAddedToPersistentStore(int32 download_id, 1051 void DownloadManagerImpl::OnSavePageItemAddedToPersistentStore(
1032 int64 db_handle) { 1052 int32 download_id, int64 db_handle) {
1033 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1053 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1034 1054
1035 DownloadMap::const_iterator it = save_page_downloads_.find(download_id); 1055 DownloadMap::const_iterator it = save_page_downloads_.find(download_id);
1036 // This can happen if the download manager is shutting down and all maps 1056 // This can happen if the download manager is shutting down and all maps
1037 // have been cleared. 1057 // have been cleared.
1038 if (it == save_page_downloads_.end()) 1058 if (it == save_page_downloads_.end())
1039 return; 1059 return;
1040 1060
1041 DownloadItem* download = it->second; 1061 DownloadItem* download = it->second;
1042 if (!download) { 1062 if (!download) {
1043 NOTREACHED(); 1063 NOTREACHED();
1044 return; 1064 return;
1045 } 1065 }
1046 1066
1047 // TODO(rdsmith): Remove after http://crbug.com/85408 resolved. 1067 // TODO(rdsmith): Remove after http://crbug.com/85408 resolved.
1048 int64 largest_handle = largest_db_handle_in_history_; 1068 int64 largest_handle = largest_db_handle_in_history_;
1049 base::debug::Alias(&largest_handle); 1069 base::debug::Alias(&largest_handle);
1050 CHECK(!ContainsKey(history_downloads_, db_handle)); 1070 CHECK(!ContainsKey(history_downloads_, db_handle));
1051 1071
1052 AddDownloadItemToHistory(download, db_handle); 1072 AddDownloadItemToHistory(download, db_handle);
1053 1073
1054 // Finalize this download if it finished before the history callback. 1074 // Finalize this download if it finished before the history callback.
1055 if (!download->IsInProgress()) 1075 if (!download->IsInProgress())
1056 SavePageDownloadFinished(download); 1076 SavePageDownloadFinished(download);
1057 } 1077 }
1058 1078
1059 void DownloadManager::SavePageDownloadFinished(DownloadItem* download) { 1079 void DownloadManagerImpl::SavePageDownloadFinished(DownloadItem* download) {
1060 if (download->db_handle() != DownloadItem::kUninitializedHandle) { 1080 if (download->db_handle() != DownloadItem::kUninitializedHandle) {
1061 delegate_->UpdateItemInPersistentStore(download); 1081 delegate_->UpdateItemInPersistentStore(download);
1062 DCHECK(ContainsKey(save_page_downloads_, download->id())); 1082 DCHECK(ContainsKey(save_page_downloads_, download->id()));
1063 save_page_downloads_.erase(download->id()); 1083 save_page_downloads_.erase(download->id());
1064 1084
1065 if (download->IsComplete()) 1085 if (download->IsComplete())
1066 content::NotificationService::current()->Notify( 1086 content::NotificationService::current()->Notify(
1067 content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED, 1087 content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED,
1068 content::Source<DownloadManager>(this), 1088 content::Source<DownloadManager>(this),
1069 content::Details<DownloadItem>(download)); 1089 content::Details<DownloadItem>(download));
1070 } 1090 }
1071 } 1091 }
1072 1092
1073 void DownloadManager::MarkDownloadOpened(DownloadItem* download) { 1093 void DownloadManagerImpl::MarkDownloadOpened(DownloadItem* download) {
1074 delegate_->UpdateItemInPersistentStore(download); 1094 delegate_->UpdateItemInPersistentStore(download);
1075 int num_unopened = 0; 1095 int num_unopened = 0;
1076 for (DownloadMap::iterator it = history_downloads_.begin(); 1096 for (DownloadMap::iterator it = history_downloads_.begin();
1077 it != history_downloads_.end(); ++it) { 1097 it != history_downloads_.end(); ++it) {
1078 if (it->second->IsComplete() && !it->second->opened()) 1098 if (it->second->IsComplete() && !it->second->opened())
1079 ++num_unopened; 1099 ++num_unopened;
1080 } 1100 }
1081 download_stats::RecordOpensOutstanding(num_unopened); 1101 download_stats::RecordOpensOutstanding(num_unopened);
1082 } 1102 }
1103
1104 void DownloadManagerImpl::SetFileManager(DownloadFileManager* file_manager) {
1105 file_manager_ = file_manager;
1106 }
OLDNEW
« no previous file with comments | « content/browser/download/download_manager_impl.h ('k') | content/browser/download/mock_download_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698