Chromium Code Reviews| 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" |
| 11 #include "chrome/browser/profiles/profile.h" | 11 #include "chrome/browser/profiles/profile.h" |
| 12 #include "content/public/browser/browser_context.h" | 12 #include "content/public/browser/browser_context.h" |
| 13 #include "content/public/browser/browser_thread.h" | 13 #include "content/public/browser/browser_thread.h" |
| 14 #include "content/public/browser/web_contents.h" | 14 #include "content/public/browser/web_contents.h" |
| 15 #include "net/base/network_change_notifier.h" | 15 #include "net/base/network_change_notifier.h" |
| 16 #include "ui/gfx/geometry/size.h" | 16 #include "ui/gfx/geometry/size.h" |
| 17 | 17 |
| 18 namespace offline_pages { | 18 namespace offline_pages { |
| 19 | 19 |
| 20 // Classifies whether final status represent a canceled operation vs. a full | |
|
Dmitry Titov
2016/09/24 00:53:30
Could you clarify the comment? Both options sound
Pete Williamson
2016/09/27 19:25:07
This may be better to return an enum CANCELED or F
dougarnett
2016/09/29 01:11:23
Done.
| |
| 21 // attempt that failed. | |
| 22 bool IsCanceledOperation(prerender::FinalStatus final_status) { | |
|
chili
2016/09/23 00:44:17
nit: while both spellings are valid, I think reque
dougarnett
2016/09/23 18:20:01
Yeah, the Offliner statuses all use single L so th
| |
| 23 switch (final_status) { | |
| 24 case prerender::FINAL_STATUS_CANCELLED: | |
| 25 case prerender::FINAL_STATUS_RECENTLY_VISITED: | |
| 26 // TODO(dougarnett): Reconsider if/when get better granularity (642768) | |
| 27 case prerender::FINAL_STATUS_UNSUPPORTED_SCHEME: | |
| 28 return true; | |
| 29 default: | |
| 30 return false; | |
| 31 } | |
| 32 } | |
| 33 | |
| 34 // Classifies whether final status represent a retryable failure vs. one that | |
| 35 // should not be retried. | |
|
Pete Williamson
2016/09/27 19:25:07
Maybe combine this with the function above, and ha
dougarnett
2016/09/29 01:11:23
Done.
| |
| 36 bool IsRetryableFailure(prerender::FinalStatus final_status) { | |
| 37 switch (final_status) { | |
| 38 case prerender::FINAL_STATUS_SAFE_BROWSING: | |
| 39 case prerender::FINAL_STATUS_CREATING_AUDIO_STREAM: | |
| 40 case prerender::FINAL_STATUS_JAVASCRIPT_ALERT: | |
| 41 return false; | |
| 42 default: | |
| 43 return true; | |
| 44 } | |
| 45 } | |
| 46 | |
| 20 PrerenderingLoader::PrerenderingLoader(content::BrowserContext* browser_context) | 47 PrerenderingLoader::PrerenderingLoader(content::BrowserContext* browser_context) |
| 21 : state_(State::IDLE), | 48 : state_(State::IDLE), |
| 22 snapshot_controller_(nullptr), | 49 snapshot_controller_(nullptr), |
| 23 browser_context_(browser_context) { | 50 browser_context_(browser_context) { |
| 24 adapter_.reset(new PrerenderAdapter(this)); | 51 adapter_.reset(new PrerenderAdapter(this)); |
| 25 } | 52 } |
| 26 | 53 |
| 27 PrerenderingLoader::~PrerenderingLoader() { | 54 PrerenderingLoader::~PrerenderingLoader() { |
| 28 CancelPrerender(); | 55 CancelPrerender(); |
| 29 } | 56 } |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 154 // Loading has stopped so unless the Loader has already transistioned to the | 181 // Loading has stopped so unless the Loader has already transistioned to the |
| 155 // idle state, clean up the previous request state, transition to the idle | 182 // idle state, clean up the previous request state, transition to the idle |
| 156 // state, and post callback. | 183 // state, and post callback. |
| 157 // Note: it is possible to receive some asynchronous stopped indication after | 184 // Note: it is possible to receive some asynchronous stopped indication after |
| 158 // the request has completed/stopped via another path so the Loader may be | 185 // the request has completed/stopped via another path so the Loader may be |
| 159 // idle at this point. | 186 // idle at this point. |
| 160 | 187 |
| 161 if (IsIdle()) | 188 if (IsIdle()) |
| 162 return; | 189 return; |
| 163 | 190 |
| 164 // Request status depends on whether we are still loading (failed) or | 191 // If we have already loaded, then the prerender stack is now canceling |
|
Dmitry Titov
2016/09/24 00:53:30
Same, this comment is not clear. loaded means canc
dougarnett
2016/09/29 01:11:23
Done.
| |
| 165 // did load and then loading was stopped (cancel - from prerender stack). | 192 // the operation (before we may be done with the WebContents). Otherwise, |
| 193 // the baseline case is a prerender failure but we will consider the | |
| 194 // prerender final status subsequently to refine the status. | |
| 166 Offliner::RequestStatus request_status = | 195 Offliner::RequestStatus request_status = |
| 167 IsLoaded() ? Offliner::RequestStatus::PRERENDERING_CANCELED | 196 IsLoaded() ? Offliner::RequestStatus::PRERENDERING_CANCELED |
| 168 : Offliner::RequestStatus::PRERENDERING_FAILED; | 197 : Offliner::RequestStatus::PRERENDERING_FAILED; |
| 169 | 198 |
| 170 if (adapter_->IsActive()) { | 199 if (adapter_->IsActive()) { |
| 171 prerender::FinalStatus final_status = adapter_->GetFinalStatus(); | 200 prerender::FinalStatus final_status = adapter_->GetFinalStatus(); |
| 172 DVLOG(1) << "Load failed: " << final_status; | 201 DVLOG(1) << "Load failed: " << final_status; |
| 173 | 202 |
| 203 if (IsCanceledOperation(final_status)) { | |
| 204 request_status = Offliner::RequestStatus::PRERENDERING_CANCELED; | |
| 205 } else if (!IsRetryableFailure(final_status)) { | |
| 206 request_status = Offliner::RequestStatus::PRERENDERING_FAILED_NO_RETRY; | |
| 207 } | |
| 208 | |
| 174 // Loss of network connection can show up as unsupported scheme per | 209 // Loss of network connection can show up as unsupported scheme per |
| 175 // a redirect to a special data URL is used to navigate to error page. | 210 // a redirect to a special data URL is used to navigate to error page. |
| 176 // We want to be able to retry these request so for now treat any | 211 // Capture the current connectivity here in case we can leverage that |
| 177 // unsupported scheme error as a cancel. | 212 // to differentiate how to treat it. |
| 178 // TODO(dougarnett): Use new FinalStatus code if/when supported (642768). | 213 if (final_status == prerender::FINAL_STATUS_UNSUPPORTED_SCHEME) { |
|
Pete Williamson
2016/09/27 19:25:07
Why stop emitting UMA for cancels?
dougarnett
2016/09/29 01:11:23
There was no UMA for cancels here - just setting t
| |
| 179 // TODO(dougarnett): Create whitelist of final status codes that should | |
| 180 // not be considered failures (and define new RequestStatus code for them). | |
| 181 if (adapter_->GetFinalStatus() == | |
| 182 prerender::FinalStatus::FINAL_STATUS_UNSUPPORTED_SCHEME) { | |
| 183 request_status = Offliner::RequestStatus::PRERENDERING_CANCELED; | |
| 184 UMA_HISTOGRAM_ENUMERATION( | 214 UMA_HISTOGRAM_ENUMERATION( |
| 185 "OfflinePages.Background.UnsupportedScheme.ConnectionType", | 215 "OfflinePages.Background.UnsupportedScheme.ConnectionType", |
| 186 net::NetworkChangeNotifier::GetConnectionType(), | 216 net::NetworkChangeNotifier::GetConnectionType(), |
| 187 net::NetworkChangeNotifier::ConnectionType::CONNECTION_LAST + 1); | 217 net::NetworkChangeNotifier::ConnectionType::CONNECTION_LAST + 1); |
| 188 } | 218 } |
| 189 adapter_->DestroyActive(); | 219 adapter_->DestroyActive(); |
| 190 } | 220 } |
| 191 | 221 |
| 192 snapshot_controller_.reset(nullptr); | 222 snapshot_controller_.reset(nullptr); |
| 193 session_contents_.reset(nullptr); | 223 session_contents_.reset(nullptr); |
| 194 state_ = State::IDLE; | 224 state_ = State::IDLE; |
| 195 base::ThreadTaskRunnerHandle::Get()->PostTask( | 225 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 196 FROM_HERE, base::Bind(callback_, request_status, nullptr)); | 226 FROM_HERE, base::Bind(callback_, request_status, nullptr)); |
| 197 } | 227 } |
| 198 | 228 |
| 199 void PrerenderingLoader::CancelPrerender() { | 229 void PrerenderingLoader::CancelPrerender() { |
| 200 if (adapter_->IsActive()) { | 230 if (adapter_->IsActive()) { |
| 201 adapter_->DestroyActive(); | 231 adapter_->DestroyActive(); |
| 202 } | 232 } |
| 203 snapshot_controller_.reset(nullptr); | 233 snapshot_controller_.reset(nullptr); |
| 204 session_contents_.reset(nullptr); | 234 session_contents_.reset(nullptr); |
| 205 state_ = State::IDLE; | 235 state_ = State::IDLE; |
| 206 } | 236 } |
| 207 | 237 |
| 208 } // namespace offline_pages | 238 } // namespace offline_pages |
| OLD | NEW |