OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/android/offline_pages/prerendering_loader.h" | 5 #include "chrome/browser/android/offline_pages/prerendering_loader.h" |
6 | 6 |
7 #include "base/location.h" | 7 #include "base/location.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/metrics/histogram_macros.h" | 9 #include "base/metrics/histogram_macros.h" |
10 #include "base/threading/thread_task_runner_handle.h" | 10 #include "base/threading/thread_task_runner_handle.h" |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 snapshot_controller_(nullptr), | 81 snapshot_controller_(nullptr), |
82 browser_context_(browser_context) { | 82 browser_context_(browser_context) { |
83 adapter_.reset(new PrerenderAdapter(this)); | 83 adapter_.reset(new PrerenderAdapter(this)); |
84 } | 84 } |
85 | 85 |
86 PrerenderingLoader::~PrerenderingLoader() { | 86 PrerenderingLoader::~PrerenderingLoader() { |
87 CancelPrerender(); | 87 CancelPrerender(); |
88 } | 88 } |
89 | 89 |
90 bool PrerenderingLoader::LoadPage(const GURL& url, | 90 bool PrerenderingLoader::LoadPage(const GURL& url, |
91 const LoadPageCallback& callback) { | 91 const LoadPageCallback& load_done_callback, |
| 92 const ProgressCallback& progress_callback) { |
92 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 93 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
93 if (!IsIdle()) { | 94 if (!IsIdle()) { |
94 DVLOG(1) | 95 DVLOG(1) |
95 << "WARNING: Existing request in progress or waiting for StopLoading()"; | 96 << "WARNING: Existing request in progress or waiting for StopLoading()"; |
96 return false; | 97 return false; |
97 } | 98 } |
98 | 99 |
99 // Create a WebContents instance to define and hold a SessionStorageNamespace | 100 // Create a WebContents instance to define and hold a SessionStorageNamespace |
100 // for this load request. | 101 // for this load request. |
101 DCHECK(!session_contents_.get()); | 102 DCHECK(!session_contents_.get()); |
102 std::unique_ptr<content::WebContents> new_web_contents( | 103 std::unique_ptr<content::WebContents> new_web_contents( |
103 content::WebContents::Create( | 104 content::WebContents::Create( |
104 content::WebContents::CreateParams(browser_context_))); | 105 content::WebContents::CreateParams(browser_context_))); |
105 content::SessionStorageNamespace* sessionStorageNamespace = | 106 content::SessionStorageNamespace* sessionStorageNamespace = |
106 new_web_contents->GetController().GetDefaultSessionStorageNamespace(); | 107 new_web_contents->GetController().GetDefaultSessionStorageNamespace(); |
107 gfx::Size renderWindowSize = new_web_contents->GetContainerBounds().size(); | 108 gfx::Size renderWindowSize = new_web_contents->GetContainerBounds().size(); |
108 bool accepted = adapter_->StartPrerender( | 109 bool accepted = adapter_->StartPrerender( |
109 browser_context_, url, sessionStorageNamespace, renderWindowSize); | 110 browser_context_, url, sessionStorageNamespace, renderWindowSize); |
110 if (!accepted) | 111 if (!accepted) |
111 return false; | 112 return false; |
112 | 113 |
113 DCHECK(adapter_->IsActive()); | 114 DCHECK(adapter_->IsActive()); |
114 snapshot_controller_.reset( | 115 snapshot_controller_.reset( |
115 new SnapshotController(base::ThreadTaskRunnerHandle::Get(), this, | 116 new SnapshotController(base::ThreadTaskRunnerHandle::Get(), this, |
116 kOfflinePageDclDelayMs, | 117 kOfflinePageDclDelayMs, |
117 kOfflinePageOnloadDelayMs)); | 118 kOfflinePageOnloadDelayMs)); |
118 callback_ = callback; | 119 load_done_callback_ = load_done_callback; |
| 120 progress_callback_ = progress_callback; |
119 session_contents_.swap(new_web_contents); | 121 session_contents_.swap(new_web_contents); |
120 state_ = State::LOADING; | 122 state_ = State::LOADING; |
121 return true; | 123 return true; |
122 } | 124 } |
123 | 125 |
124 void PrerenderingLoader::StopLoading() { | 126 void PrerenderingLoader::StopLoading() { |
125 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 127 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
126 CancelPrerender(); | 128 CancelPrerender(); |
127 } | 129 } |
128 | 130 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 // second delay from this event). | 165 // second delay from this event). |
164 snapshot_controller_->DocumentAvailableInMainFrame(); | 166 snapshot_controller_->DocumentAvailableInMainFrame(); |
165 } | 167 } |
166 } | 168 } |
167 | 169 |
168 void PrerenderingLoader::OnPrerenderStop() { | 170 void PrerenderingLoader::OnPrerenderStop() { |
169 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 171 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
170 HandleLoadingStopped(); | 172 HandleLoadingStopped(); |
171 } | 173 } |
172 | 174 |
| 175 void PrerenderingLoader::OnPrerenderNetworkBytesChanged(int64_t bytes) { |
| 176 if (state_ == State::LOADING) |
| 177 progress_callback_.Run(bytes); |
| 178 } |
| 179 |
173 void PrerenderingLoader::StartSnapshot() { | 180 void PrerenderingLoader::StartSnapshot() { |
174 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 181 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
175 HandleLoadEvent(); | 182 HandleLoadEvent(); |
176 } | 183 } |
177 | 184 |
178 void PrerenderingLoader::HandleLoadEvent() { | 185 void PrerenderingLoader::HandleLoadEvent() { |
179 // If still loading, check if the load succeeded or not, then update | 186 // If still loading, check if the load succeeded or not, then update |
180 // the internal state (LOADED for success or IDLE for failure) and post | 187 // the internal state (LOADED for success or IDLE for failure) and post |
181 // callback. | 188 // callback. |
182 // Note: it is possible to receive a load event (e.g., if timeout-based) | 189 // Note: it is possible to receive a load event (e.g., if timeout-based) |
183 // after the request has completed via another path (e.g., canceled) so | 190 // after the request has completed via another path (e.g., canceled) so |
184 // the Loader may be idle at this point. | 191 // the Loader may be idle at this point. |
185 | 192 |
186 if (IsIdle() || IsLoaded()) | 193 if (IsIdle() || IsLoaded()) |
187 return; | 194 return; |
188 | 195 |
189 content::WebContents* web_contents = adapter_->GetWebContents(); | 196 content::WebContents* web_contents = adapter_->GetWebContents(); |
190 if (web_contents) { | 197 if (web_contents) { |
191 state_ = State::LOADED; | 198 state_ = State::LOADED; |
192 base::ThreadTaskRunnerHandle::Get()->PostTask( | 199 base::ThreadTaskRunnerHandle::Get()->PostTask( |
193 FROM_HERE, | 200 FROM_HERE, base::Bind(load_done_callback_, |
194 base::Bind(callback_, Offliner::RequestStatus::LOADED, web_contents)); | 201 Offliner::RequestStatus::LOADED, web_contents)); |
195 } else { | 202 } else { |
196 // No WebContents means that the load failed (and it stopped). | 203 // No WebContents means that the load failed (and it stopped). |
197 HandleLoadingStopped(); | 204 HandleLoadingStopped(); |
198 } | 205 } |
199 } | 206 } |
200 | 207 |
201 void PrerenderingLoader::HandleLoadingStopped() { | 208 void PrerenderingLoader::HandleLoadingStopped() { |
202 // Loading has stopped so unless the Loader has already transitioned to the | 209 // Loading has stopped so unless the Loader has already transitioned to the |
203 // idle state, clean up the previous request state, transition to the idle | 210 // idle state, clean up the previous request state, transition to the idle |
204 // state, and post callback. | 211 // state, and post callback. |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 adapter_->DestroyActive(); | 245 adapter_->DestroyActive(); |
239 } else { | 246 } else { |
240 // No access to FinalStatus so classify as retryable failure. | 247 // No access to FinalStatus so classify as retryable failure. |
241 request_status = Offliner::RequestStatus::LOADING_FAILED; | 248 request_status = Offliner::RequestStatus::LOADING_FAILED; |
242 } | 249 } |
243 | 250 |
244 snapshot_controller_.reset(nullptr); | 251 snapshot_controller_.reset(nullptr); |
245 session_contents_.reset(nullptr); | 252 session_contents_.reset(nullptr); |
246 state_ = State::IDLE; | 253 state_ = State::IDLE; |
247 base::ThreadTaskRunnerHandle::Get()->PostTask( | 254 base::ThreadTaskRunnerHandle::Get()->PostTask( |
248 FROM_HERE, base::Bind(callback_, request_status, nullptr)); | 255 FROM_HERE, base::Bind(load_done_callback_, request_status, nullptr)); |
249 } | 256 } |
250 | 257 |
251 void PrerenderingLoader::CancelPrerender() { | 258 void PrerenderingLoader::CancelPrerender() { |
252 if (adapter_->IsActive()) { | 259 if (adapter_->IsActive()) { |
253 adapter_->DestroyActive(); | 260 adapter_->DestroyActive(); |
254 } | 261 } |
255 snapshot_controller_.reset(nullptr); | 262 snapshot_controller_.reset(nullptr); |
256 session_contents_.reset(nullptr); | 263 session_contents_.reset(nullptr); |
257 state_ = State::IDLE; | 264 state_ = State::IDLE; |
258 } | 265 } |
259 | 266 |
260 } // namespace offline_pages | 267 } // namespace offline_pages |
OLD | NEW |