chili | 1ae92b9 | 2016-12-19 21:53:27 | [diff] [blame] | 1 | // 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 | |
dimich | d733a61 | 2017-05-16 21:36:48 | [diff] [blame] | 5 | #ifndef CHROME_BROWSER_OFFLINE_PAGES_BACKGROUND_LOADER_OFFLINER_H_ |
| 6 | #define CHROME_BROWSER_OFFLINE_PAGES_BACKGROUND_LOADER_OFFLINER_H_ |
chili | 1ae92b9 | 2016-12-19 21:53:27 | [diff] [blame] | 7 | |
| 8 | #include <memory> |
| 9 | |
chili | 1ae92b9 | 2016-12-19 21:53:27 | [diff] [blame] | 10 | #include "base/memory/weak_ptr.h" |
petewil | b009196 | 2017-04-20 17:46:35 | [diff] [blame] | 11 | #include "base/values.h" |
petewil | 7c8537f | 2017-06-16 23:03:15 | [diff] [blame] | 12 | #include "chrome/browser/offline_pages/resource_loading_observer.h" |
chili | 1ae92b9 | 2016-12-19 21:53:27 | [diff] [blame] | 13 | #include "components/offline_pages/content/background_loader/background_loader_contents.h" |
dimich | 9149485 | 2017-05-25 17:36:04 | [diff] [blame] | 14 | #include "components/offline_pages/core/background/load_termination_listener.h" |
chili | 1ae92b9 | 2016-12-19 21:53:27 | [diff] [blame] | 15 | #include "components/offline_pages/core/background/offliner.h" |
Pete Williamson | cfcecd0 | 2018-07-26 17:30:51 | [diff] [blame] | 16 | #include "components/offline_pages/core/background_snapshot_controller.h" |
chili | 1ae92b9 | 2016-12-19 21:53:27 | [diff] [blame] | 17 | #include "components/offline_pages/core/offline_page_types.h" |
chili | 1ae92b9 | 2016-12-19 21:53:27 | [diff] [blame] | 18 | #include "content/public/browser/web_contents_observer.h" |
| 19 | |
| 20 | namespace content { |
| 21 | class BrowserContext; |
| 22 | } // namespace content |
| 23 | |
| 24 | namespace offline_pages { |
| 25 | |
chili | 8dbcb895 | 2017-01-10 21:33:12 | [diff] [blame] | 26 | class OfflinerPolicy; |
chili | 1ae92b9 | 2016-12-19 21:53:27 | [diff] [blame] | 27 | class OfflinePageModel; |
| 28 | |
Collin Baker | 4f19f1a8 | 2017-08-08 23:49:12 | [diff] [blame] | 29 | class PageRenovationLoader; |
| 30 | class PageRenovator; |
| 31 | |
Pete Williamson | 2f4fffab | 2017-06-27 20:06:49 | [diff] [blame] | 32 | struct RequestStats { |
| 33 | int requested; |
| 34 | int completed; |
| 35 | |
| 36 | RequestStats() : requested(0), completed(0) {} |
| 37 | }; |
| 38 | |
chili | 1ae92b9 | 2016-12-19 21:53:27 | [diff] [blame] | 39 | // 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 Li | 1d2614b | 2018-02-12 20:25:25 | [diff] [blame] | 42 | class BackgroundLoaderOffliner |
| 43 | : public Offliner, |
| 44 | public background_loader::BackgroundLoaderContents::Delegate, |
| 45 | public content::WebContentsObserver, |
Pete Williamson | cfcecd0 | 2018-07-26 17:30:51 | [diff] [blame] | 46 | public BackgroundSnapshotController::Client, |
Cathy Li | 1d2614b | 2018-02-12 20:25:25 | [diff] [blame] | 47 | public ResourceLoadingObserver { |
chili | 1ae92b9 | 2016-12-19 21:53:27 | [diff] [blame] | 48 | public: |
dimich | 9149485 | 2017-05-25 17:36:04 | [diff] [blame] | 49 | BackgroundLoaderOffliner( |
| 50 | content::BrowserContext* browser_context, |
| 51 | const OfflinerPolicy* policy, |
| 52 | OfflinePageModel* offline_page_model, |
| 53 | std::unique_ptr<LoadTerminationListener> load_termination_listener); |
chili | 1ae92b9 | 2016-12-19 21:53:27 | [diff] [blame] | 54 | ~BackgroundLoaderOffliner() override; |
| 55 | |
chili | f2fc623 | 2017-03-15 19:21:52 | [diff] [blame] | 56 | static BackgroundLoaderOffliner* FromWebContents( |
| 57 | content::WebContents* contents); |
| 58 | |
chili | 1ae92b9 | 2016-12-19 21:53:27 | [diff] [blame] | 59 | // Offliner implementation. |
| 60 | bool LoadAndSave(const SavePageRequest& request, |
Yafei Duan | 1dd0228 | 2018-05-11 23:51:39 | [diff] [blame] | 61 | CompletionCallback completion_callback, |
dimich | 0e2f6cb | 2017-03-08 17:44:00 | [diff] [blame] | 62 | const ProgressCallback& progress_callback) override; |
Yafei Duan | 1dd0228 | 2018-05-11 23:51:39 | [diff] [blame] | 63 | bool Cancel(CancelCallback callback) override; |
dimich | 9149485 | 2017-05-25 17:36:04 | [diff] [blame] | 64 | void TerminateLoadIfInProgress() override; |
fgorski | 3d9408b3 | 2017-04-25 16:36:30 | [diff] [blame] | 65 | bool HandleTimeout(int64_t request_id) override; |
chili | 1ae92b9 | 2016-12-19 21:53:27 | [diff] [blame] | 66 | |
Cathy Li | 1d2614b | 2018-02-12 20:25:25 | [diff] [blame] | 67 | // 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 | |
chili | 1ae92b9 | 2016-12-19 21:53:27 | [diff] [blame] | 73 | // WebContentsObserver implementation. |
chili | c92ef59 | 2017-04-11 21:44:16 | [diff] [blame] | 74 | void DocumentAvailableInMainFrame() override; |
| 75 | void DocumentOnLoadCompletedInMainFrame() override; |
chili | b13fb4e3 | 2017-01-03 18:36:19 | [diff] [blame] | 76 | void RenderProcessGone(base::TerminationStatus status) override; |
| 77 | void WebContentsDestroyed() override; |
chili | 9194158 | 2017-02-13 23:20:10 | [diff] [blame] | 78 | void DidFinishNavigation( |
| 79 | content::NavigationHandle* navigation_handle) override; |
chili | 1ae92b9 | 2016-12-19 21:53:27 | [diff] [blame] | 80 | |
Pete Williamson | cfcecd0 | 2018-07-26 17:30:51 | [diff] [blame] | 81 | // BackgroundSnapshotController::Client implementation. |
chili | e101d81 | 2017-03-28 01:24:23 | [diff] [blame] | 82 | void StartSnapshot() override; |
Collin Baker | a453f98 | 2017-07-21 17:40:12 | [diff] [blame] | 83 | void RunRenovations() override; |
chili | e101d81 | 2017-03-28 01:24:23 | [diff] [blame] | 84 | |
Pete Williamson | cfcecd0 | 2018-07-26 17:30:51 | [diff] [blame] | 85 | void SetBackgroundSnapshotControllerForTest( |
| 86 | std::unique_ptr<BackgroundSnapshotController> controller); |
petewil | 7c8537f | 2017-06-16 23:03:15 | [diff] [blame] | 87 | |
| 88 | // ResourceLoadingObserver implemenation |
| 89 | void ObserveResourceLoading(ResourceLoadingObserver::ResourceDataType type, |
| 90 | bool started) override; |
| 91 | void OnNetworkBytesChanged(int64_t bytes) override; |
chili | 632b3bc | 2017-02-27 23:15:46 | [diff] [blame] | 92 | |
chili | 1ae92b9 | 2016-12-19 21:53:27 | [diff] [blame] | 93 | protected: |
chili | e427c753 | 2017-05-08 04:11:49 | [diff] [blame] | 94 | // Called to reset the loader. |
| 95 | virtual void ResetLoader(); |
chili | 1ae92b9 | 2016-12-19 21:53:27 | [diff] [blame] | 96 | |
| 97 | private: |
| 98 | friend class TestBackgroundLoaderOffliner; |
Pete Williamson | 2f4fffab | 2017-06-27 20:06:49 | [diff] [blame] | 99 | friend class BackgroundLoaderOfflinerTest; |
chili | 1ae92b9 | 2016-12-19 21:53:27 | [diff] [blame] | 100 | |
| 101 | enum SaveState { NONE, SAVING, DELETE_AFTER_SAVE }; |
Candice Sy | 8ec3395 | 2018-03-29 00:27:17 | [diff] [blame] | 102 | enum PageLoadState { |
| 103 | SUCCESS, |
| 104 | RETRIABLE_NET_ERROR, |
| 105 | RETRIABLE_HTTP_ERROR, |
| 106 | NONRETRIABLE |
| 107 | }; |
chili | 1ae92b9 | 2016-12-19 21:53:27 | [diff] [blame] | 108 | |
| 109 | // Called when the page has been saved. |
| 110 | void OnPageSaved(SavePageResult save_result, int64_t offline_id); |
| 111 | |
chili | e427c753 | 2017-05-08 04:11:49 | [diff] [blame] | 112 | // 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 | |
petewil | b009196 | 2017-04-20 17:46:35 | [diff] [blame] | 118 | // 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 Baker | 4f19f1a8 | 2017-08-08 23:49:12 | [diff] [blame] | 124 | // Called by PageRenovator callback when renovations complete. |
| 125 | void RenovationsCompleted(); |
| 126 | |
petewil | 2915191 | 2017-05-02 00:51:09 | [diff] [blame] | 127 | void DeleteOfflinePageCallback(const SavePageRequest& request, |
| 128 | DeletePageResult result); |
| 129 | |
Pete Williamson | 2f4fffab | 2017-06-27 20:06:49 | [diff] [blame] | 130 | // Testing method to examine resource stats. |
| 131 | RequestStats* GetRequestStatsForTest() { return stats_; } |
| 132 | |
chili | 1ae92b9 | 2016-12-19 21:53:27 | [diff] [blame] | 133 | std::unique_ptr<background_loader::BackgroundLoaderContents> loader_; |
| 134 | // Not owned. |
| 135 | content::BrowserContext* browser_context_; |
| 136 | // Not owned. |
| 137 | OfflinePageModel* offline_page_model_; |
chili | 3bcd846 | 2017-04-18 01:04:36 | [diff] [blame] | 138 | // Not owned. |
| 139 | const OfflinerPolicy* policy_; |
chili | 1ae92b9 | 2016-12-19 21:53:27 | [diff] [blame] | 140 | // Tracks pending request, if any. |
| 141 | std::unique_ptr<SavePageRequest> pending_request_; |
chili | e101d81 | 2017-03-28 01:24:23 | [diff] [blame] | 142 | // Handles determining when a page should be snapshotted. |
Pete Williamson | cfcecd0 | 2018-07-26 17:30:51 | [diff] [blame] | 143 | std::unique_ptr<BackgroundSnapshotController> snapshot_controller_; |
chili | 1ae92b9 | 2016-12-19 21:53:27 | [diff] [blame] | 144 | // Callback when pending request completes. |
| 145 | CompletionCallback completion_callback_; |
chili | f2fc623 | 2017-03-15 19:21:52 | [diff] [blame] | 146 | // Callback to report progress. |
| 147 | ProgressCallback progress_callback_; |
dimich | 9149485 | 2017-05-25 17:36:04 | [diff] [blame] | 148 | // LoadTerminationListener to monitor external conditions requiring immediate |
| 149 | // termination of the offlining operation (memory conditions etc). |
| 150 | std::unique_ptr<LoadTerminationListener> load_termination_listener_; |
chili | 1ae92b9 | 2016-12-19 21:53:27 | [diff] [blame] | 151 | // Whether we are on a low-end device. |
| 152 | bool is_low_end_device_; |
chili | 9f04f39d | 2017-03-04 01:23:56 | [diff] [blame] | 153 | |
Collin Baker | 4f19f1a8 | 2017-08-08 23:49:12 | [diff] [blame] | 154 | // 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 | |
chili | 1ae92b9 | 2016-12-19 21:53:27 | [diff] [blame] | 159 | // Save state. |
| 160 | SaveState save_state_; |
chili | 9194158 | 2017-02-13 23:20:10 | [diff] [blame] | 161 | // Page load state. |
| 162 | PageLoadState page_load_state_; |
chili | f2fc623 | 2017-03-15 19:21:52 | [diff] [blame] | 163 | // Network bytes loaded. |
| 164 | int64_t network_bytes_; |
chili | 3bcd846 | 2017-04-18 01:04:36 | [diff] [blame] | 165 | // 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_; |
chili | 1ae92b9 | 2016-12-19 21:53:27 | [diff] [blame] | 169 | |
petewil | b009196 | 2017-04-20 17:46:35 | [diff] [blame] | 170 | // 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 | |
chili | 9f04f39d | 2017-03-04 01:23:56 | [diff] [blame] | 177 | // Callback for cancel. |
| 178 | CancelCallback cancel_callback_; |
| 179 | |
Pete Williamson | 2f4fffab | 2017-06-27 20:06:49 | [diff] [blame] | 180 | // Holds stats for resource request status for resource types we track. |
| 181 | RequestStats stats_[ResourceDataType::RESOURCE_DATA_TYPE_COUNT]; |
petewil | d277ad3 | 2017-06-22 18:14:39 | [diff] [blame] | 182 | |
chili | 1ae92b9 | 2016-12-19 21:53:27 | [diff] [blame] | 183 | base::WeakPtrFactory<BackgroundLoaderOffliner> weak_ptr_factory_; |
| 184 | DISALLOW_COPY_AND_ASSIGN(BackgroundLoaderOffliner); |
| 185 | }; |
| 186 | |
| 187 | } // namespace offline_pages |
dimich | d733a61 | 2017-05-16 21:36:48 | [diff] [blame] | 188 | #endif // CHROME_BROWSER_OFFLINE_PAGES_BACKGROUND_LOADER_OFFLINER_H_ |