• 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/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 
DownloadService(Profile * profile)26 DownloadService::DownloadService(Profile* profile)
27     : download_manager_created_(false),
28       profile_(profile) {
29 }
30 
~DownloadService()31 DownloadService::~DownloadService() {}
32 
GetDownloadManagerDelegate()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 
GetDownloadHistory()79 DownloadHistory* DownloadService::GetDownloadHistory() {
80   if (!download_manager_created_) {
81     GetDownloadManagerDelegate();
82   }
83   DCHECK(download_manager_created_);
84   return download_history_.get();
85 }
86 
HasCreatedDownloadManager()87 bool DownloadService::HasCreatedDownloadManager() {
88   return download_manager_created_;
89 }
90 
NonMaliciousDownloadCount() const91 int DownloadService::NonMaliciousDownloadCount() const {
92   if (!download_manager_created_)
93     return 0;
94   return BrowserContext::GetDownloadManager(profile_)->
95       NonMaliciousInProgressCount();
96 }
97 
98 // static
NonMaliciousDownloadCountAllProfiles()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
CancelAllDownloads()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 
SetDownloadManagerDelegateForTesting(scoped_ptr<ChromeDownloadManagerDelegate> new_delegate)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 
IsShelfEnabled()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 
Shutdown()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