15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/download/download_service.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/download/chrome_download_manager_delegate.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/download/download_history.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/download/download_service_factory.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/download/download_status_updater.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/download/download_ui_controller.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/api/downloads/downloads_api.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/history_service.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/history_service_factory.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/net/chrome_net_log.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/download_manager.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserContext; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::DownloadManager; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::DownloadManagerDelegate; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DownloadService::DownloadService(Profile* profile) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : download_manager_created_(false), 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_(profile) { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DownloadService::~DownloadService() {} 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChromeDownloadManagerDelegate* DownloadService::GetDownloadManagerDelegate() { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadManager* manager = BrowserContext::GetDownloadManager(profile_); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we've already created the delegate, just return it. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (download_manager_created_) { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(static_cast<DownloadManagerDelegate*>(manager_delegate_.get()) == 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager->GetDelegate()); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return manager_delegate_.get(); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) download_manager_created_ = true; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In case the delegate has already been set by 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SetDownloadManagerDelegateForTesting. 45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!manager_delegate_.get()) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager_delegate_ = new ChromeDownloadManagerDelegate(profile_); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager_delegate_->SetDownloadManager(manager); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_ANDROID) 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_event_router_.reset(new ExtensionDownloadsEventRouter( 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile_, manager)); 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!profile_->IsOffTheRecord()) { 567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch HistoryService* history = HistoryServiceFactory::GetForProfile( 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile_, Profile::EXPLICIT_ACCESS); 587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch history->GetNextDownloadId(base::Bind( 597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch &ChromeDownloadManagerDelegate::SetNextId, manager_delegate_)); 607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch download_history_.reset(new DownloadHistory( 617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch manager, 627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_ptr<DownloadHistory::HistoryAdapter>( 637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch new DownloadHistory::HistoryAdapter(history)))); 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Pass an empty delegate when constructing the DownloadUIController. The 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // default delegate does all the notifications we need. 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<DownloadUIController::Delegate> empty_ui_delegate; 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download_ui_.reset(new DownloadUIController(manager, 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) empty_ui_delegate.Pass())); 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Include this download manager in the set monitored by the 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // global status updater. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_browser_process->download_status_updater()->AddManager(manager); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return manager_delegate_.get(); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DownloadHistory* DownloadService::GetDownloadHistory() { 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!download_manager_created_) { 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetDownloadManagerDelegate(); 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(download_manager_created_); 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return download_history_.get(); 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DownloadService::HasCreatedDownloadManager() { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return download_manager_created_; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int DownloadService::DownloadCount() const { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!download_manager_created_) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return BrowserContext::GetDownloadManager(profile_)->InProgressCount(); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int DownloadService::DownloadCountAllProfiles() { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Profile*> profiles( 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_browser_process->profile_manager()->GetLoadedProfiles()); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int count = 0; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<Profile*>::iterator it = profiles.begin(); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it < profiles.end(); ++it) { 105a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) count += DownloadServiceFactory::GetForBrowserContext(*it)->DownloadCount(); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*it)->HasOffTheRecordProfile()) 107a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) count += DownloadServiceFactory::GetForBrowserContext( 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*it)->GetOffTheRecordProfile())->DownloadCount(); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return count; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DownloadService::SetDownloadManagerDelegateForTesting( 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChromeDownloadManagerDelegate* new_delegate) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the new delegate first so that if BrowserContext::GetDownloadManager() 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // causes a new download manager to be created, we won't create a redundant 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ChromeDownloadManagerDelegate(). 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager_delegate_ = new_delegate; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Guarantee everything is properly initialized. 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadManager* dm = BrowserContext::GetDownloadManager(profile_); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dm->GetDelegate() != new_delegate) { 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dm->SetDelegate(new_delegate); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_delegate->SetDownloadManager(dm); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 128a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool DownloadService::IsShelfEnabled() { 129a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#if defined(OS_ANDROID) 130a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return true; 131a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#else 132a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return !extension_event_router_ || 133a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) extension_event_router_->IsShelfEnabled(); 134a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#endif 135a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 136a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DownloadService::Shutdown() { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (download_manager_created_) { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Normally the DownloadManager would be shutdown later, after the Profile 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // goes away and BrowserContext's destructor runs. But that would be too 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // late for us since we need to use the profile (indirectly through history 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // code) when the DownloadManager is shutting down. So we shut it down 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // manually earlier. See http://crbug.com/131692 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserContext::GetDownloadManager(profile_)->Shutdown(); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_ANDROID) 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_event_router_.reset(); 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager_delegate_ = NULL; 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download_history_.reset(); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 152