1 // Copyright 2017 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_factory.h"
6 
7 #include <memory>
8 #include <utility>
9 
10 #include "base/feature_list.h"
11 #include "base/files/file_path.h"
12 #include "base/memory/singleton.h"
13 #include "base/sequenced_task_runner.h"
14 #include "base/single_thread_task_runner.h"
15 #include "base/task/task_traits.h"
16 #include "base/task/thread_pool.h"
17 #include "chrome/browser/background_fetch/background_fetch_download_client.h"
18 #include "chrome/browser/chromeos/plugin_vm/plugin_vm_image_download_client.h"
19 #include "chrome/browser/download/deferred_client_wrapper.h"
20 #include "chrome/browser/download/download_manager_utils.h"
21 #include "chrome/browser/download/download_task_scheduler_impl.h"
22 #include "chrome/browser/download/simple_download_manager_coordinator_factory.h"
23 #include "chrome/browser/net/system_network_context_manager.h"
24 #include "chrome/browser/profiles/incognito_helpers.h"
25 #include "chrome/browser/profiles/profile.h"
26 #include "chrome/browser/profiles/profile_key.h"
27 #include "chrome/browser/transition_manager/full_browser_transition_manager.h"
28 #include "chrome/common/chrome_constants.h"
29 #include "components/download/content/factory/download_service_factory_helper.h"
30 #include "components/download/content/factory/navigation_monitor_factory.h"
31 #include "components/download/public/background_service/blob_context_getter_factory.h"
32 #include "components/download/public/background_service/clients.h"
33 #include "components/download/public/background_service/download_service.h"
34 #include "components/download/public/background_service/features.h"
35 #include "components/download/public/common/simple_download_manager_coordinator.h"
36 #include "components/download/public/task/task_scheduler.h"
37 #include "components/keyed_service/core/simple_dependency_manager.h"
38 #include "components/leveldb_proto/public/proto_database_provider.h"
39 #include "components/offline_pages/buildflags/buildflags.h"
40 #include "content/public/browser/browser_context.h"
41 #include "content/public/browser/browser_task_traits.h"
42 #include "content/public/browser/browser_thread.h"
43 #include "content/public/browser/download_manager.h"
44 #include "content/public/browser/network_service_instance.h"
45 #include "content/public/browser/storage_partition.h"
46 
47 #if defined(OS_ANDROID)
48 #include "chrome/browser/download/android/service/download_task_scheduler.h"
49 #endif
50 
51 #if BUILDFLAG(ENABLE_OFFLINE_PAGES)
52 #include "chrome/browser/offline_pages/prefetch/offline_prefetch_download_client.h"
53 #endif
54 
55 namespace {
56 
CreateBackgroundFetchDownloadClient(Profile * profile)57 std::unique_ptr<download::Client> CreateBackgroundFetchDownloadClient(
58     Profile* profile) {
59   return std::make_unique<BackgroundFetchDownloadClient>(profile);
60 }
61 
62 #if defined(OS_CHROMEOS)
CreatePluginVmImageDownloadClient(Profile * profile)63 std::unique_ptr<download::Client> CreatePluginVmImageDownloadClient(
64     Profile* profile) {
65   return std::make_unique<plugin_vm::PluginVmImageDownloadClient>(profile);
66 }
67 #endif
68 
69 // Called on profile created to retrieve the BlobStorageContextGetter.
DownloadOnProfileCreated(download::BlobContextGetterCallback callback,Profile * profile)70 void DownloadOnProfileCreated(download::BlobContextGetterCallback callback,
71                               Profile* profile) {
72   auto blob_context_getter =
73       content::BrowserContext::GetBlobStorageContext(profile);
74   DCHECK(callback);
75   std::move(callback).Run(blob_context_getter);
76 }
77 
78 // Provides BlobContextGetter from Chrome asynchronously.
79 class DownloadBlobContextGetterFactory
80     : public download::BlobContextGetterFactory {
81  public:
DownloadBlobContextGetterFactory(SimpleFactoryKey * key)82   explicit DownloadBlobContextGetterFactory(SimpleFactoryKey* key) : key_(key) {
83     DCHECK(key_);
84   }
85   ~DownloadBlobContextGetterFactory() override = default;
86 
87  private:
88   // download::BlobContextGetterFactory implementation.
RetrieveBlobContextGetter(download::BlobContextGetterCallback callback)89   void RetrieveBlobContextGetter(
90       download::BlobContextGetterCallback callback) override {
91     FullBrowserTransitionManager::Get()->RegisterCallbackOnProfileCreation(
92         key_, base::BindOnce(&DownloadOnProfileCreated, std::move(callback)));
93   }
94 
95   SimpleFactoryKey* key_;
96   DISALLOW_COPY_AND_ASSIGN(DownloadBlobContextGetterFactory);
97 };
98 
99 }  // namespace
100 
101 // static
GetInstance()102 DownloadServiceFactory* DownloadServiceFactory::GetInstance() {
103   return base::Singleton<DownloadServiceFactory>::get();
104 }
105 
106 // static
GetForKey(SimpleFactoryKey * key)107 download::DownloadService* DownloadServiceFactory::GetForKey(
108     SimpleFactoryKey* key) {
109   return static_cast<download::DownloadService*>(
110       GetInstance()->GetServiceForKey(key, true));
111 }
112 
DownloadServiceFactory()113 DownloadServiceFactory::DownloadServiceFactory()
114     : SimpleKeyedServiceFactory("download::DownloadService",
115                                 SimpleDependencyManager::GetInstance()) {
116   DependsOn(SimpleDownloadManagerCoordinatorFactory::GetInstance());
117   DependsOn(download::NavigationMonitorFactory::GetInstance());
118 }
119 
120 DownloadServiceFactory::~DownloadServiceFactory() = default;
121 
BuildServiceInstanceFor(SimpleFactoryKey * key) const122 std::unique_ptr<KeyedService> DownloadServiceFactory::BuildServiceInstanceFor(
123     SimpleFactoryKey* key) const {
124   auto clients = std::make_unique<download::DownloadClientMap>();
125   ProfileKey* profile_key = ProfileKey::FromSimpleFactoryKey(key);
126 
127 #if BUILDFLAG(ENABLE_OFFLINE_PAGES)
128   // Offline prefetch doesn't support incognito.
129   if (!key->IsOffTheRecord()) {
130     clients->insert(std::make_pair(
131         download::DownloadClient::OFFLINE_PAGE_PREFETCH,
132         std::make_unique<offline_pages::OfflinePrefetchDownloadClient>(key)));
133   }
134 #endif  // BUILDFLAG(ENABLE_OFFLINE_PAGES)
135 
136   clients->insert(std::make_pair(
137       download::DownloadClient::BACKGROUND_FETCH,
138       std::make_unique<download::DeferredClientWrapper>(
139           base::BindOnce(&CreateBackgroundFetchDownloadClient), key)));
140 
141 #if defined(OS_CHROMEOS)
142   if (!key->IsOffTheRecord()) {
143     clients->insert(std::make_pair(
144         download::DownloadClient::PLUGIN_VM_IMAGE,
145         std::make_unique<download::DeferredClientWrapper>(
146             base::BindOnce(&CreatePluginVmImageDownloadClient), key)));
147   }
148 #endif
149 
150   // Build in memory download service for incognito profile.
151   if (key->IsOffTheRecord() &&
152       base::FeatureList::IsEnabled(download::kDownloadServiceIncognito)) {
153     auto blob_context_getter_factory =
154         std::make_unique<DownloadBlobContextGetterFactory>(key);
155     scoped_refptr<base::SingleThreadTaskRunner> io_task_runner =
156         content::GetIOThreadTaskRunner({});
157     scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory =
158         SystemNetworkContextManager::GetInstance()->GetSharedURLLoaderFactory();
159 
160     return download::BuildInMemoryDownloadService(
161         key, std::move(clients), content::GetNetworkConnectionTracker(),
162         base::FilePath(), std::move(blob_context_getter_factory),
163         io_task_runner, url_loader_factory);
164   } else {
165     // Build download service for normal profile.
166     base::FilePath storage_dir;
167     if (!key->IsOffTheRecord() && !key->GetPath().empty()) {
168       storage_dir =
169           key->GetPath().Append(chrome::kDownloadServiceStorageDirname);
170     }
171     scoped_refptr<base::SequencedTaskRunner> background_task_runner =
172         base::ThreadPool::CreateSequencedTaskRunner(
173             {base::MayBlock(), base::TaskPriority::BEST_EFFORT});
174 
175     std::unique_ptr<download::TaskScheduler> task_scheduler;
176 #if defined(OS_ANDROID)
177     task_scheduler =
178         std::make_unique<download::android::DownloadTaskScheduler>();
179 #else
180     task_scheduler = std::make_unique<DownloadTaskSchedulerImpl>(key);
181 #endif
182     // Some tests doesn't initialize DownloadManager when profile is created,
183     // and cause the download service to fail. Call
184     // InitializeSimpleDownloadManager() to initialize the DownloadManager
185     // whenever profile becomes available.
186     DownloadManagerUtils::InitializeSimpleDownloadManager(profile_key);
187     leveldb_proto::ProtoDatabaseProvider* proto_db_provider =
188         profile_key->GetProtoDatabaseProvider();
189     return download::BuildDownloadService(
190         key, std::move(clients), content::GetNetworkConnectionTracker(),
191         storage_dir, SimpleDownloadManagerCoordinatorFactory::GetForKey(key),
192         proto_db_provider, background_task_runner, std::move(task_scheduler));
193   }
194 }
195 
GetKeyToUse(SimpleFactoryKey * key) const196 SimpleFactoryKey* DownloadServiceFactory::GetKeyToUse(
197     SimpleFactoryKey* key) const {
198   return key;
199 }
200