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/background_loader_offliner.h" | 5 #include "chrome/browser/android/offline_pages/background_loader_offliner.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/json/json_writer.h" | 8 #include "base/json/json_writer.h" |
| 9 #include "base/metrics/histogram_macros.h" | 9 #include "base/metrics/histogram_macros.h" |
| 10 #include "base/sys_info.h" | 10 #include "base/sys_info.h" |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 165 static_cast<int>(OfflinePagesCctApiPrerenderAllowedStatus:: | 165 static_cast<int>(OfflinePagesCctApiPrerenderAllowedStatus:: |
| 166 NETWORK_PREDICTION_DISABLED) + | 166 NETWORK_PREDICTION_DISABLED) + |
| 167 1); | 167 1); |
| 168 } | 168 } |
| 169 | 169 |
| 170 if (!OfflinePageModel::CanSaveURL(request.url())) { | 170 if (!OfflinePageModel::CanSaveURL(request.url())) { |
| 171 DVLOG(1) << "Not able to save page for requested url: " << request.url(); | 171 DVLOG(1) << "Not able to save page for requested url: " << request.url(); |
| 172 return false; | 172 return false; |
| 173 } | 173 } |
| 174 | 174 |
| 175 if (!loader_) | 175 ResetLoader(); |
| 176 ResetState(); | 176 AttachObservers(); |
| 177 | 177 |
| 178 MarkLoadStartTime(); | 178 MarkLoadStartTime(); |
| 179 | 179 |
| 180 // Track copy of pending request. | 180 // Track copy of pending request. |
| 181 pending_request_.reset(new SavePageRequest(request)); | 181 pending_request_.reset(new SavePageRequest(request)); |
| 182 completion_callback_ = completion_callback; | 182 completion_callback_ = completion_callback; |
| 183 progress_callback_ = progress_callback; | 183 progress_callback_ = progress_callback; |
| 184 | 184 |
| 185 // Listen for app foreground/background change. | 185 // Listen for app foreground/background change. |
| 186 app_listener_.reset(new base::android::ApplicationStatusListener( | 186 app_listener_.reset(new base::android::ApplicationStatusListener( |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 279 Offliner::RequestStatus::LOADING_FAILED); | 279 Offliner::RequestStatus::LOADING_FAILED); |
| 280 } | 280 } |
| 281 ResetState(); | 281 ResetState(); |
| 282 } | 282 } |
| 283 } | 283 } |
| 284 | 284 |
| 285 void BackgroundLoaderOffliner::WebContentsDestroyed() { | 285 void BackgroundLoaderOffliner::WebContentsDestroyed() { |
| 286 if (pending_request_) { | 286 if (pending_request_) { |
| 287 SavePageRequest request(*pending_request_.get()); | 287 SavePageRequest request(*pending_request_.get()); |
| 288 completion_callback_.Run(request, Offliner::RequestStatus::LOADING_FAILED); | 288 completion_callback_.Run(request, Offliner::RequestStatus::LOADING_FAILED); |
| 289 ResetState(); | 289 ResetState(); |
|
dewittj
2017/05/05 21:26:16
nit: ResetState will cause a double-free of the de
chili
2017/05/05 21:34:23
I still can't think of a good way to fix this. Wit
carlosk
2017/05/05 21:49:48
Can you detect when that situation is happening --
chili
2017/05/06 00:21:17
We currently don't have a good way of figuring out
| |
| 290 } | 290 } |
| 291 } | 291 } |
| 292 | 292 |
| 293 void BackgroundLoaderOffliner::DidFinishNavigation( | 293 void BackgroundLoaderOffliner::DidFinishNavigation( |
| 294 content::NavigationHandle* navigation_handle) { | 294 content::NavigationHandle* navigation_handle) { |
| 295 if (!navigation_handle->IsInMainFrame()) | 295 if (!navigation_handle->IsInMainFrame()) |
| 296 return; | 296 return; |
| 297 // If there was an error of any kind (certificate, client, DNS, etc), | 297 // If there was an error of any kind (certificate, client, DNS, etc), |
| 298 // Mark as error page. Resetting here causes RecordNavigationMetrics to crash. | 298 // Mark as error page. Resetting here causes RecordNavigationMetrics to crash. |
| 299 if (navigation_handle->IsErrorPage()) { | 299 if (navigation_handle->IsErrorPage()) { |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 446 cancel_callback_.Run(request); | 446 cancel_callback_.Run(request); |
| 447 } | 447 } |
| 448 | 448 |
| 449 void BackgroundLoaderOffliner::ResetState() { | 449 void BackgroundLoaderOffliner::ResetState() { |
| 450 pending_request_.reset(); | 450 pending_request_.reset(); |
| 451 snapshot_controller_.reset(); | 451 snapshot_controller_.reset(); |
| 452 page_load_state_ = SUCCESS; | 452 page_load_state_ = SUCCESS; |
| 453 network_bytes_ = 0LL; | 453 network_bytes_ = 0LL; |
| 454 is_low_bar_met_ = false; | 454 is_low_bar_met_ = false; |
| 455 did_snapshot_on_last_retry_ = false; | 455 did_snapshot_on_last_retry_ = false; |
| 456 // TODO(chili): Remove after RequestCoordinator can handle multiple offliners. | 456 content::WebContentsObserver::Observe(nullptr); |
| 457 // We reset the loader and observer after completion so loaders | 457 loader_.reset(); |
| 458 // will not be re-used across different requests/tries. This is a temporary | 458 } |
| 459 // solution while there exists assumptions about the number of offliners | 459 |
| 460 // there are. | 460 void BackgroundLoaderOffliner::ResetLoader() { |
| 461 loader_.reset( | 461 loader_.reset( |
| 462 new background_loader::BackgroundLoaderContents(browser_context_)); | 462 new background_loader::BackgroundLoaderContents(browser_context_)); |
| 463 } | |
| 464 | |
| 465 void BackgroundLoaderOffliner::AttachObservers() { | |
| 463 content::WebContents* contents = loader_->web_contents(); | 466 content::WebContents* contents = loader_->web_contents(); |
| 464 content::WebContentsObserver::Observe(contents); | 467 content::WebContentsObserver::Observe(contents); |
| 465 OfflinerData::AddToWebContents(contents, this); | 468 OfflinerData::AddToWebContents(contents, this); |
| 466 } | 469 } |
| 467 | 470 |
| 468 void BackgroundLoaderOffliner::OnApplicationStateChange( | 471 void BackgroundLoaderOffliner::OnApplicationStateChange( |
| 469 base::android::ApplicationState application_state) { | 472 base::android::ApplicationState application_state) { |
| 470 if (pending_request_ && is_low_end_device_ && | 473 if (pending_request_ && is_low_end_device_ && |
| 471 application_state == | 474 application_state == |
| 472 base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) { | 475 base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) { |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 486 // Given the choice between int and double, we choose to implicitly convert to | 489 // Given the choice between int and double, we choose to implicitly convert to |
| 487 // a double since it maintains more precision (we can get a longer time in | 490 // a double since it maintains more precision (we can get a longer time in |
| 488 // milliseconds than we can with a 2 bit int, 53 bits vs 32). | 491 // milliseconds than we can with a 2 bit int, 53 bits vs 32). |
| 489 double delay = delay_so_far.InMilliseconds(); | 492 double delay = delay_so_far.InMilliseconds(); |
| 490 signal_data_.SetDouble(signal_name, delay); | 493 signal_data_.SetDouble(signal_name, delay); |
| 491 } | 494 } |
| 492 | 495 |
| 493 } // namespace offline_pages | 496 } // namespace offline_pages |
| 494 | 497 |
| 495 DEFINE_WEB_CONTENTS_USER_DATA_KEY(offline_pages::OfflinerData); | 498 DEFINE_WEB_CONTENTS_USER_DATA_KEY(offline_pages::OfflinerData); |
| OLD | NEW |