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 #ifndef COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_DISPATCHER_IMPL_H_
6 #define COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_DISPATCHER_IMPL_H_
7 
8 #include <map>
9 #include <memory>
10 #include <set>
11 #include <string>
12 #include <utility>
13 #include <vector>
14 
15 #include "base/macros.h"
16 #include "base/memory/weak_ptr.h"
17 #include "components/offline_pages/core/offline_page_types.h"
18 #include "components/offline_pages/core/prefetch/prefetch_dispatcher.h"
19 #include "components/offline_pages/core/prefetch/server_forbidden_check_request.h"
20 #include "components/offline_pages/core/prefetch/suggestions_provider.h"
21 #include "components/offline_pages/core/prefetch/tasks/get_visuals_info_task.h"
22 #include "components/offline_pages/task/task_queue.h"
23 #include "components/version_info/channel.h"
24 
25 class PrefService;
26 
27 namespace offline_pages {
28 class PrefetchService;
29 struct PrefetchSuggestion;
30 
31 class PrefetchDispatcherImpl : public PrefetchDispatcher,
32                                public TaskQueue::Delegate {
33  public:
34   explicit PrefetchDispatcherImpl(PrefService* pref_service);
35   ~PrefetchDispatcherImpl() override;
36 
37   // PrefetchDispatcher implementation:
38   void SetService(PrefetchService* service) override;
39   void EnsureTaskScheduled() override;
40   void SchedulePipelineProcessing() override;
41   void AddCandidatePrefetchURLs(
42       const std::string& name_space,
43       const std::vector<PrefetchURL>& prefetch_urls) override;
44   void NewSuggestionsAvailable(
45       SuggestionsProvider* suggestions_provider) override;
46   void RemoveSuggestion(const GURL& url) override;
47   void RemoveAllUnprocessedPrefetchURLs(const std::string& name_space) override;
48   void RemovePrefetchURLsByClientId(const ClientId& client_id) override;
49   void BeginBackgroundTask(
50       std::unique_ptr<PrefetchBackgroundTask> background_task) override;
51   void StopBackgroundTask() override;
52   void GCMOperationCompletedMessageReceived(
53       const std::string& operation_name) override;
54   void CleanupDownloads(
55       const std::set<std::string>& outstanding_download_ids,
56       const std::map<std::string, std::pair<base::FilePath, int64_t>>&
57           success_downloads) override;
58   void GeneratePageBundleRequested(std::unique_ptr<IdsVector> ids) override;
59   void DownloadCompleted(
60       const PrefetchDownloadResult& download_result) override;
61   void ItemDownloaded(int64_t offline_id, const ClientId& client_id) override;
62   void ArchiveImported(int64_t offline_id, bool success) override;
63 
64   // TaskQueue::Delegate implementation:
65   void OnTaskQueueIsIdle() override;
66 
67  private:
68   friend class PrefetchDispatcherTest;
69 
GetWeakPtr()70   base::WeakPtr<PrefetchDispatcherImpl> GetWeakPtr() {
71     return weak_factory_.GetWeakPtr();
72   }
73 
74   void DisposeTask();
75 
76   // Callbacks for network requests.
77   void DidGenerateBundleOrGetOperationRequest(
78       const std::string& request_name_for_logging,
79       PrefetchRequestStatus status,
80       const std::string& operation_name,
81       const std::vector<RenderPageInfo>& pages);
82   void LogRequestResult(const std::string& request_name_for_logging,
83                         PrefetchRequestStatus status,
84                         const std::string& operation_name,
85                         const std::vector<RenderPageInfo>& pages);
86 
87   // Adds the Reconcile tasks to the TaskQueue. These look for error/stuck
88   // processing conditions that happen as result of Chrome being evicted
89   // or network failures of certain kind. They are run on periodic wakeup
90   // (BeginBackgroundTask()). See PrefetchDispatcher interface
91   // declaration for Reconcile tasks definition.
92   void QueueReconcileTasks();
93   // Adds the Action tasks to the queue. See PrefetchDispatcher interface
94   // declaration for Action tasks definition.
95   // Action tasks can be added to the queue either in response to periodic
96   // wakeup (when BeginBackgroundTask() is called) or any time TaskQueue
97   // becomes idle and any task called SchedulePipelineProcessing() before.
98   void QueueActionTasks();
99   // Adds a list of PrefetchSuggestions to the queue of suggestions to be
100   // prefetched.
101   void AddSuggestions(std::vector<PrefetchSuggestion> suggestions);
102 
103   // The methods below control the  downloading of visuals for the provided
104   // prefetch items IDs. They are called multiple times for the same article,
105   // when they reach different points in the pipeline to increase the likeliness
106   // of the thumbnail to be available. The existence of the thumbnail is
107   // verified to avoid re-downloads.
108   // Also, even though unlikely, concurrent calls to these methods are
109   // supported. They will generate simultaneous download attempts but there will
110   // be no impact in the consistency of stored data.
111   // TODO(carlosk): This logic has become complex and holds too much state
112   // throughout the calls. It should be moved into a separate class (possibly
113   // internal to the implementation) to make it easier to maintain and
114   // understand.
115   void FetchVisuals(std::unique_ptr<IdsVector> remaining_ids,
116                     bool is_first_attempt);
117   void VisualsAvailabilityChecked(int64_t offline_id,
118                                   ClientId client_id,
119                                   std::unique_ptr<IdsVector> remaining_ids,
120                                   bool is_first_attempt,
121                                   VisualsAvailability availability);
122   void VisualsInfoReceived(int64_t offline_id,
123                            std::unique_ptr<IdsVector> remaining_ids,
124                            bool is_first_attempt,
125                            VisualsAvailability availability,
126                            GetVisualsInfoTask::Result result);
127   void ThumbnailFetchComplete(int64_t offline_id,
128                               std::unique_ptr<IdsVector> remaining_ids,
129                               bool is_first_attempt,
130                               const GURL& favicon_url,
131                               const std::string& thumbnail);
132   void FetchFavicon(int64_t offline_id,
133                     std::unique_ptr<IdsVector> remaining_ids,
134                     bool is_first_attempt,
135                     const GURL& favicon_url);
136   void FaviconFetchComplete(int64_t offline_id,
137                             std::unique_ptr<IdsVector> remaining_ids,
138                             bool is_first_attempt,
139                             const std::string& favicon_data);
140 
141   PrefService* pref_service_;
142   PrefetchService* service_;
143   TaskQueue task_queue_;
144   bool needs_pipeline_processing_ = false;
145   bool suspended_ = false;
146   std::unique_ptr<PrefetchBackgroundTask> background_task_;
147   base::WeakPtrFactory<PrefetchDispatcherImpl> weak_factory_{this};
148 
149   DISALLOW_COPY_AND_ASSIGN(PrefetchDispatcherImpl);
150 };
151 
152 }  // namespace offline_pages
153 
154 #endif  // COMPONENTS_OFFLINE_PAGES_CORE_PREFETCH_PREFETCH_DISPATCHER_IMPL_H_
155