blob: ae020b0b17f0e62cb78f8fd59ca6298a1ed8774e [file] [log] [blame]
chili1ae92b92016-12-19 21:53:271// Copyright 2016 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
dimichd733a612017-05-16 21:36:485#ifndef CHROME_BROWSER_OFFLINE_PAGES_BACKGROUND_LOADER_OFFLINER_H_
6#define CHROME_BROWSER_OFFLINE_PAGES_BACKGROUND_LOADER_OFFLINER_H_
chili1ae92b92016-12-19 21:53:277
8#include <memory>
9
chili1ae92b92016-12-19 21:53:2710#include "base/memory/weak_ptr.h"
petewilb0091962017-04-20 17:46:3511#include "base/values.h"
petewil7c8537f2017-06-16 23:03:1512#include "chrome/browser/offline_pages/resource_loading_observer.h"
chili1ae92b92016-12-19 21:53:2713#include "components/offline_pages/content/background_loader/background_loader_contents.h"
dimich91494852017-05-25 17:36:0414#include "components/offline_pages/core/background/load_termination_listener.h"
chili1ae92b92016-12-19 21:53:2715#include "components/offline_pages/core/background/offliner.h"
Pete Williamsoncfcecd02018-07-26 17:30:5116#include "components/offline_pages/core/background_snapshot_controller.h"
chili1ae92b92016-12-19 21:53:2717#include "components/offline_pages/core/offline_page_types.h"
chili1ae92b92016-12-19 21:53:2718#include "content/public/browser/web_contents_observer.h"
19
20namespace content {
21class BrowserContext;
22} // namespace content
23
24namespace offline_pages {
25
chili8dbcb8952017-01-10 21:33:1226class OfflinerPolicy;
chili1ae92b92016-12-19 21:53:2727class OfflinePageModel;
28
Collin Baker4f19f1a82017-08-08 23:49:1229class PageRenovationLoader;
30class PageRenovator;
31
Pete Williamson2f4fffab2017-06-27 20:06:4932struct RequestStats {
33 int requested;
34 int completed;
35
36 RequestStats() : requested(0), completed(0) {}
37};
38
chili1ae92b92016-12-19 21:53:2739// An Offliner implementation that attempts client-side rendering and saving
40// of an offline page. It uses the BackgroundLoader to load the page and the
41// OfflinePageModel to save it. Only one request may be active at a time.
Cathy Li1d2614b2018-02-12 20:25:2542class BackgroundLoaderOffliner
43 : public Offliner,
44 public background_loader::BackgroundLoaderContents::Delegate,
45 public content::WebContentsObserver,
Pete Williamsoncfcecd02018-07-26 17:30:5146 public BackgroundSnapshotController::Client,
Cathy Li1d2614b2018-02-12 20:25:2547 public ResourceLoadingObserver {
chili1ae92b92016-12-19 21:53:2748 public:
dimich91494852017-05-25 17:36:0449 BackgroundLoaderOffliner(
50 content::BrowserContext* browser_context,
51 const OfflinerPolicy* policy,
52 OfflinePageModel* offline_page_model,
53 std::unique_ptr<LoadTerminationListener> load_termination_listener);
chili1ae92b92016-12-19 21:53:2754 ~BackgroundLoaderOffliner() override;
55
chilif2fc6232017-03-15 19:21:5256 static BackgroundLoaderOffliner* FromWebContents(
57 content::WebContents* contents);
58
chili1ae92b92016-12-19 21:53:2759 // Offliner implementation.
60 bool LoadAndSave(const SavePageRequest& request,
Yafei Duan1dd02282018-05-11 23:51:3961 CompletionCallback completion_callback,
dimich0e2f6cb2017-03-08 17:44:0062 const ProgressCallback& progress_callback) override;
Yafei Duan1dd02282018-05-11 23:51:3963 bool Cancel(CancelCallback callback) override;
dimich91494852017-05-25 17:36:0464 void TerminateLoadIfInProgress() override;
fgorski3d9408b32017-04-25 16:36:3065 bool HandleTimeout(int64_t request_id) override;
chili1ae92b92016-12-19 21:53:2766
Cathy Li1d2614b2018-02-12 20:25:2567 // BackgroundLoaderContents::Delegate implementation.
68 // Called when a navigation resulted in a single-file download. e.g.
69 // When user navigated to a pdf page while offline and clicks on the
70 // "Download page later" button.
71 void CanDownload(const base::Callback<void(bool)>& callback) override;
72
chili1ae92b92016-12-19 21:53:2773 // WebContentsObserver implementation.
chilic92ef592017-04-11 21:44:1674 void DocumentAvailableInMainFrame() override;
75 void DocumentOnLoadCompletedInMainFrame() override;
chilib13fb4e32017-01-03 18:36:1976 void RenderProcessGone(base::TerminationStatus status) override;
77 void WebContentsDestroyed() override;
chili91941582017-02-13 23:20:1078 void DidFinishNavigation(
79 content::NavigationHandle* navigation_handle) override;
chili1ae92b92016-12-19 21:53:2780
Pete Williamsoncfcecd02018-07-26 17:30:5181 // BackgroundSnapshotController::Client implementation.
chilie101d812017-03-28 01:24:2382 void StartSnapshot() override;
Collin Bakera453f982017-07-21 17:40:1283 void RunRenovations() override;
chilie101d812017-03-28 01:24:2384
Pete Williamsoncfcecd02018-07-26 17:30:5185 void SetBackgroundSnapshotControllerForTest(
86 std::unique_ptr<BackgroundSnapshotController> controller);
petewil7c8537f2017-06-16 23:03:1587
88 // ResourceLoadingObserver implemenation
89 void ObserveResourceLoading(ResourceLoadingObserver::ResourceDataType type,
90 bool started) override;
91 void OnNetworkBytesChanged(int64_t bytes) override;
chili632b3bc2017-02-27 23:15:4692
chili1ae92b92016-12-19 21:53:2793 protected:
chilie427c7532017-05-08 04:11:4994 // Called to reset the loader.
95 virtual void ResetLoader();
chili1ae92b92016-12-19 21:53:2796
97 private:
98 friend class TestBackgroundLoaderOffliner;
Pete Williamson2f4fffab2017-06-27 20:06:4999 friend class BackgroundLoaderOfflinerTest;
chili1ae92b92016-12-19 21:53:27100
101 enum SaveState { NONE, SAVING, DELETE_AFTER_SAVE };
Candice Sy8ec33952018-03-29 00:27:17102 enum PageLoadState {
103 SUCCESS,
104 RETRIABLE_NET_ERROR,
105 RETRIABLE_HTTP_ERROR,
106 NONRETRIABLE
107 };
chili1ae92b92016-12-19 21:53:27108
109 // Called when the page has been saved.
110 void OnPageSaved(SavePageResult save_result, int64_t offline_id);
111
chilie427c7532017-05-08 04:11:49112 // Called to reset internal loader and observer state.
113 void ResetState();
114
115 // Called to attach 'this' as the observer to the loader.
116 void AttachObservers();
117
petewilb0091962017-04-20 17:46:35118 // Called to remember at what time we started loading.
119 void MarkLoadStartTime();
120
121 // Called to add a loading signal as we observe it.
122 void AddLoadingSignal(const char* signal_name);
123
Collin Baker4f19f1a82017-08-08 23:49:12124 // Called by PageRenovator callback when renovations complete.
125 void RenovationsCompleted();
126
petewil29151912017-05-02 00:51:09127 void DeleteOfflinePageCallback(const SavePageRequest& request,
128 DeletePageResult result);
129
Pete Williamson2f4fffab2017-06-27 20:06:49130 // Testing method to examine resource stats.
131 RequestStats* GetRequestStatsForTest() { return stats_; }
132
chili1ae92b92016-12-19 21:53:27133 std::unique_ptr<background_loader::BackgroundLoaderContents> loader_;
134 // Not owned.
135 content::BrowserContext* browser_context_;
136 // Not owned.
137 OfflinePageModel* offline_page_model_;
chili3bcd8462017-04-18 01:04:36138 // Not owned.
139 const OfflinerPolicy* policy_;
chili1ae92b92016-12-19 21:53:27140 // Tracks pending request, if any.
141 std::unique_ptr<SavePageRequest> pending_request_;
chilie101d812017-03-28 01:24:23142 // Handles determining when a page should be snapshotted.
Pete Williamsoncfcecd02018-07-26 17:30:51143 std::unique_ptr<BackgroundSnapshotController> snapshot_controller_;
chili1ae92b92016-12-19 21:53:27144 // Callback when pending request completes.
145 CompletionCallback completion_callback_;
chilif2fc6232017-03-15 19:21:52146 // Callback to report progress.
147 ProgressCallback progress_callback_;
dimich91494852017-05-25 17:36:04148 // LoadTerminationListener to monitor external conditions requiring immediate
149 // termination of the offlining operation (memory conditions etc).
150 std::unique_ptr<LoadTerminationListener> load_termination_listener_;
chili1ae92b92016-12-19 21:53:27151 // Whether we are on a low-end device.
152 bool is_low_end_device_;
chili9f04f39d2017-03-04 01:23:56153
Collin Baker4f19f1a82017-08-08 23:49:12154 // PageRenovationLoader must live longer than the PageRenovator.
155 std::unique_ptr<PageRenovationLoader> page_renovation_loader_;
156 // Per-offliner PageRenovator instance.
157 std::unique_ptr<PageRenovator> page_renovator_;
158
chili1ae92b92016-12-19 21:53:27159 // Save state.
160 SaveState save_state_;
chili91941582017-02-13 23:20:10161 // Page load state.
162 PageLoadState page_load_state_;
chilif2fc6232017-03-15 19:21:52163 // Network bytes loaded.
164 int64_t network_bytes_;
chili3bcd8462017-04-18 01:04:36165 // Whether the low bar of snapshot quality has been met.
166 bool is_low_bar_met_;
167 // Whether the snapshot is on the last retry.
168 bool did_snapshot_on_last_retry_;
chili1ae92b92016-12-19 21:53:27169
petewilb0091962017-04-20 17:46:35170 // Time in ticks of when we start loading the page.
171 base::TimeTicks load_start_time_;
172
173 // Saves loading signals.
174 // TODO(petewil): We will be replacing this with the new snapshot controller.
175 base::DictionaryValue signal_data_;
176
chili9f04f39d2017-03-04 01:23:56177 // Callback for cancel.
178 CancelCallback cancel_callback_;
179
Pete Williamson2f4fffab2017-06-27 20:06:49180 // Holds stats for resource request status for resource types we track.
181 RequestStats stats_[ResourceDataType::RESOURCE_DATA_TYPE_COUNT];
petewild277ad32017-06-22 18:14:39182
chili1ae92b92016-12-19 21:53:27183 base::WeakPtrFactory<BackgroundLoaderOffliner> weak_ptr_factory_;
184 DISALLOW_COPY_AND_ASSIGN(BackgroundLoaderOffliner);
185};
186
187} // namespace offline_pages
dimichd733a612017-05-16 21:36:48188#endif // CHROME_BROWSER_OFFLINE_PAGES_BACKGROUND_LOADER_OFFLINER_H_