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