Home | History | Annotate | Download | only in 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 
     29 DownloadService::DownloadService(Profile* profile)
     30     : download_manager_created_(false),
     31       profile_(profile) {
     32 }
     33 
     34 DownloadService::~DownloadService() {}
     35 
     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 
     81 DownloadHistory* DownloadService::GetDownloadHistory() {
     82   if (!download_manager_created_) {
     83     GetDownloadManagerDelegate();
     84   }
     85   DCHECK(download_manager_created_);
     86   return download_history_.get();
     87 }
     88 
     89 bool DownloadService::HasCreatedDownloadManager() {
     90   return download_manager_created_;
     91 }
     92 
     93 int DownloadService::NonMaliciousDownloadCount() const {
     94   if (!download_manager_created_)
     95     return 0;
     96   return BrowserContext::GetDownloadManager(profile_)->
     97       NonMaliciousInProgressCount();
     98 }
     99 
    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
    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
    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 
    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 
    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 
    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