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/offline_pages/prefetch/offline_prefetch_download_client.h"
6 
7 #include <limits>
8 #include <map>
9 #include <set>
10 #include <utility>
11 
12 #include "base/bind.h"
13 #include "base/threading/sequenced_task_runner_handle.h"
14 #include "chrome/browser/download/download_service_factory.h"
15 #include "chrome/browser/offline_pages/prefetch/prefetch_service_factory.h"
16 #include "components/download/public/background_service/download_metadata.h"
17 #include "components/offline_pages/core/prefetch/prefetch_downloader.h"
18 #include "components/offline_pages/core/prefetch/prefetch_service.h"
19 #include "services/network/public/cpp/resource_request_body.h"
20 
21 namespace offline_pages {
22 
OfflinePrefetchDownloadClient(SimpleFactoryKey * simple_factory_key)23 OfflinePrefetchDownloadClient::OfflinePrefetchDownloadClient(
24     SimpleFactoryKey* simple_factory_key)
25     : simple_factory_key_(simple_factory_key) {}
26 
27 OfflinePrefetchDownloadClient::~OfflinePrefetchDownloadClient() = default;
28 
OnServiceInitialized(bool state_lost,const std::vector<download::DownloadMetaData> & downloads)29 void OfflinePrefetchDownloadClient::OnServiceInitialized(
30     bool state_lost,
31     const std::vector<download::DownloadMetaData>& downloads) {
32   std::set<std::string> outstanding_download_guids;
33   std::map<std::string, std::pair<base::FilePath, int64_t>> success_downloads;
34   for (const auto& download : downloads) {
35     if (!download.completion_info.has_value()) {
36       outstanding_download_guids.emplace(download.guid);
37       continue;
38     }
39 
40     // Offline pages prefetch uses int64_t for file size. Check for overflow and
41     // skip it.
42     uint64_t file_size = download.completion_info->bytes_downloaded;
43     if (file_size > static_cast<uint64_t>(std::numeric_limits<int64_t>::max()))
44       continue;
45 
46     success_downloads.emplace(download.guid,
47                               std::make_pair(download.completion_info->path,
48                                              static_cast<int64_t>(file_size)));
49   }
50 
51   PrefetchDownloader* downloader = GetPrefetchDownloader();
52   if (downloader) {
53     downloader->OnDownloadServiceReady(outstanding_download_guids,
54                                        success_downloads);
55   }
56 }
57 
OnServiceUnavailable()58 void OfflinePrefetchDownloadClient::OnServiceUnavailable() {
59   PrefetchDownloader* downloader = GetPrefetchDownloader();
60   if (downloader)
61     downloader->OnDownloadServiceUnavailable();
62 }
63 
OnDownloadFailed(const std::string & guid,const download::CompletionInfo & completion_info,download::Client::FailureReason reason)64 void OfflinePrefetchDownloadClient::OnDownloadFailed(
65     const std::string& guid,
66     const download::CompletionInfo& completion_info,
67     download::Client::FailureReason reason) {
68   PrefetchDownloader* downloader = GetPrefetchDownloader();
69   if (downloader)
70     downloader->OnDownloadFailed(guid);
71 }
72 
OnDownloadSucceeded(const std::string & guid,const download::CompletionInfo & completion_info)73 void OfflinePrefetchDownloadClient::OnDownloadSucceeded(
74     const std::string& guid,
75     const download::CompletionInfo& completion_info) {
76   // Offline pages prefetch uses int64_t for file size. Check for overflow and
77   // skip it.
78   uint64_t file_size = completion_info.bytes_downloaded;
79   if (file_size > static_cast<uint64_t>(std::numeric_limits<int64_t>::max()))
80     return;
81 
82   PrefetchDownloader* downloader = GetPrefetchDownloader();
83   if (downloader)
84     downloader->OnDownloadSucceeded(guid, completion_info.path,
85                                     completion_info.bytes_downloaded);
86 }
87 
CanServiceRemoveDownloadedFile(const std::string & guid,bool force_delete)88 bool OfflinePrefetchDownloadClient::CanServiceRemoveDownloadedFile(
89     const std::string& guid,
90     bool force_delete) {
91   return true;
92 }
93 
GetUploadData(const std::string & guid,download::GetUploadDataCallback callback)94 void OfflinePrefetchDownloadClient::GetUploadData(
95     const std::string& guid,
96     download::GetUploadDataCallback callback) {
97   base::SequencedTaskRunnerHandle::Get()->PostTask(
98       FROM_HERE, base::BindOnce(std::move(callback), nullptr));
99 }
100 
GetPrefetchDownloader() const101 PrefetchDownloader* OfflinePrefetchDownloadClient::GetPrefetchDownloader()
102     const {
103   PrefetchService* prefetch_service =
104       PrefetchServiceFactory::GetForKey(simple_factory_key_);
105   if (!prefetch_service)
106     return nullptr;
107   return prefetch_service->GetPrefetchDownloader();
108 }
109 
110 }  // namespace offline_pages
111