• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)29 DownloadService::DownloadService(Profile* profile)
30     : download_manager_created_(false),
31       profile_(profile) {
32 }
33 
~DownloadService()34 DownloadService::~DownloadService() {}
35 
GetDownloadManagerDelegate()36 ChromeDownloadManagerDelegate* 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()81 DownloadHistory* DownloadService::GetDownloadHistory() {
82   if (!download_manager_created_) {
83     GetDownloadManagerDelegate();
84   }
85   DCHECK(download_manager_created_);
86   return download_history_.get();
87 }
88 
HasCreatedDownloadManager()89 bool DownloadService::HasCreatedDownloadManager() {
90   return download_manager_created_;
91 }
92 
NonMaliciousDownloadCount() const93 int DownloadService::NonMaliciousDownloadCount() const {
94   if (!download_manager_created_)
95     return 0;
96   return BrowserContext::GetDownloadManager(profile_)->
97       NonMaliciousInProgressCount();
98 }
99 
CancelDownloads()100 void 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()117 int 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()135 void 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)147 void 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()157 bool 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()166 void 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