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 "chrome/browser/download/download_service.h" 6 7#include "base/callback.h" 8#include "chrome/browser/browser_process.h" 9#include "chrome/browser/download/chrome_download_manager_delegate.h" 10#include "chrome/browser/download/download_history.h" 11#include "chrome/browser/download/download_service_factory.h" 12#include "chrome/browser/download/download_status_updater.h" 13#include "chrome/browser/download/download_ui_controller.h" 14#include "chrome/browser/history/history_service.h" 15#include "chrome/browser/history/history_service_factory.h" 16#include "chrome/browser/net/chrome_net_log.h" 17#include "chrome/browser/profiles/profile.h" 18#include "chrome/browser/profiles/profile_manager.h" 19#include "content/public/browser/download_manager.h" 20 21#if defined(ENABLE_EXTENSIONS) 22#include "chrome/browser/extensions/api/downloads/downloads_api.h" 23#endif 24 25using content::BrowserContext; 26using content::DownloadManager; 27using content::DownloadManagerDelegate; 28 29DownloadService::DownloadService(Profile* profile) 30 : download_manager_created_(false), 31 profile_(profile) { 32} 33 34DownloadService::~DownloadService() {} 35 36ChromeDownloadManagerDelegate* DownloadService::GetDownloadManagerDelegate() { 37 DownloadManager* manager = BrowserContext::GetDownloadManager(profile_); 38 // If we've already created the delegate, just return it. 39 if (download_manager_created_) { 40 DCHECK(static_cast<DownloadManagerDelegate*>(manager_delegate_.get()) == 41 manager->GetDelegate()); 42 return manager_delegate_.get(); 43 } 44 download_manager_created_ = true; 45 46 // In case the delegate has already been set by 47 // SetDownloadManagerDelegateForTesting. 48 if (!manager_delegate_.get()) 49 manager_delegate_.reset(new ChromeDownloadManagerDelegate(profile_)); 50 51 manager_delegate_->SetDownloadManager(manager); 52 53#if defined(ENABLE_EXTENSIONS) 54 extension_event_router_.reset( 55 new extensions::ExtensionDownloadsEventRouter(profile_, manager)); 56#endif 57 58 if (!profile_->IsOffTheRecord()) { 59 HistoryService* history = HistoryServiceFactory::GetForProfile( 60 profile_, Profile::EXPLICIT_ACCESS); 61 history->GetNextDownloadId( 62 manager_delegate_->GetDownloadIdReceiverCallback()); 63 download_history_.reset(new DownloadHistory( 64 manager, 65 scoped_ptr<DownloadHistory::HistoryAdapter>( 66 new DownloadHistory::HistoryAdapter(history)))); 67 } 68 69 // Pass an empty delegate when constructing the DownloadUIController. The 70 // default delegate does all the notifications we need. 71 download_ui_.reset(new DownloadUIController( 72 manager, scoped_ptr<DownloadUIController::Delegate>())); 73 74 // Include this download manager in the set monitored by the 75 // global status updater. 76 g_browser_process->download_status_updater()->AddManager(manager); 77 78 return manager_delegate_.get(); 79} 80 81DownloadHistory* DownloadService::GetDownloadHistory() { 82 if (!download_manager_created_) { 83 GetDownloadManagerDelegate(); 84 } 85 DCHECK(download_manager_created_); 86 return download_history_.get(); 87} 88 89bool DownloadService::HasCreatedDownloadManager() { 90 return download_manager_created_; 91} 92 93int DownloadService::NonMaliciousDownloadCount() const { 94 if (!download_manager_created_) 95 return 0; 96 return BrowserContext::GetDownloadManager(profile_)-> 97 NonMaliciousInProgressCount(); 98} 99 100void DownloadService::CancelDownloads() { 101 if (!download_manager_created_) 102 return; 103 104 DownloadManager* download_manager = 105 BrowserContext::GetDownloadManager(profile_); 106 DownloadManager::DownloadVector downloads; 107 download_manager->GetAllDownloads(&downloads); 108 for (DownloadManager::DownloadVector::iterator it = downloads.begin(); 109 it != downloads.end(); 110 ++it) { 111 if ((*it)->GetState() == content::DownloadItem::IN_PROGRESS) 112 (*it)->Cancel(false); 113 } 114} 115 116// static 117int DownloadService::NonMaliciousDownloadCountAllProfiles() { 118 std::vector<Profile*> profiles( 119 g_browser_process->profile_manager()->GetLoadedProfiles()); 120 121 int count = 0; 122 for (std::vector<Profile*>::iterator it = profiles.begin(); 123 it < profiles.end(); ++it) { 124 count += DownloadServiceFactory::GetForBrowserContext(*it)-> 125 NonMaliciousDownloadCount(); 126 if ((*it)->HasOffTheRecordProfile()) 127 count += DownloadServiceFactory::GetForBrowserContext( 128 (*it)->GetOffTheRecordProfile())->NonMaliciousDownloadCount(); 129 } 130 131 return count; 132} 133 134// static 135void DownloadService::CancelAllDownloads() { 136 std::vector<Profile*> profiles( 137 g_browser_process->profile_manager()->GetLoadedProfiles()); 138 for (std::vector<Profile*>::iterator it = profiles.begin(); 139 it < profiles.end(); 140 ++it) { 141 DownloadService* service = 142 DownloadServiceFactory::GetForBrowserContext(*it); 143 service->CancelDownloads(); 144 } 145} 146 147void DownloadService::SetDownloadManagerDelegateForTesting( 148 scoped_ptr<ChromeDownloadManagerDelegate> new_delegate) { 149 manager_delegate_.swap(new_delegate); 150 DownloadManager* dm = BrowserContext::GetDownloadManager(profile_); 151 dm->SetDelegate(manager_delegate_.get()); 152 manager_delegate_->SetDownloadManager(dm); 153 if (new_delegate) 154 new_delegate->Shutdown(); 155} 156 157bool DownloadService::IsShelfEnabled() { 158#if defined(OS_ANDROID) 159 return true; 160#else 161 return !extension_event_router_ || 162 extension_event_router_->IsShelfEnabled(); 163#endif 164} 165 166void DownloadService::Shutdown() { 167 if (download_manager_created_) { 168 // Normally the DownloadManager would be shutdown later, after the Profile 169 // goes away and BrowserContext's destructor runs. But that would be too 170 // late for us since we need to use the profile (indirectly through history 171 // code) when the DownloadManager is shutting down. So we shut it down 172 // manually earlier. See http://crbug.com/131692 173 BrowserContext::GetDownloadManager(profile_)->Shutdown(); 174 } 175#if defined(ENABLE_EXTENSIONS) 176 extension_event_router_.reset(); 177#endif 178 manager_delegate_.reset(); 179 download_history_.reset(); 180} 181