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 25 using content::BrowserContext; 26 using content::DownloadManager; 27 using content::DownloadManagerDelegate; 28 DownloadService(Profile * profile)29DownloadService::DownloadService(Profile* profile) 30 : download_manager_created_(false), 31 profile_(profile) { 32 } 33 ~DownloadService()34DownloadService::~DownloadService() {} 35 GetDownloadManagerDelegate()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 GetDownloadHistory()81DownloadHistory* DownloadService::GetDownloadHistory() { 82 if (!download_manager_created_) { 83 GetDownloadManagerDelegate(); 84 } 85 DCHECK(download_manager_created_); 86 return download_history_.get(); 87 } 88 HasCreatedDownloadManager()89bool DownloadService::HasCreatedDownloadManager() { 90 return download_manager_created_; 91 } 92 NonMaliciousDownloadCount() const93int DownloadService::NonMaliciousDownloadCount() const { 94 if (!download_manager_created_) 95 return 0; 96 return BrowserContext::GetDownloadManager(profile_)-> 97 NonMaliciousInProgressCount(); 98 } 99 CancelDownloads()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 NonMaliciousDownloadCountAllProfiles()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 CancelAllDownloads()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 SetDownloadManagerDelegateForTesting(scoped_ptr<ChromeDownloadManagerDelegate> new_delegate)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 IsShelfEnabled()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 Shutdown()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