Chromium Code Reviews| Index: chrome/browser/android/offline_pages/background_loader_offliner.cc |
| diff --git a/chrome/browser/android/offline_pages/background_loader_offliner.cc b/chrome/browser/android/offline_pages/background_loader_offliner.cc |
| index 2bf511a66d992509ba0bf92c682e0e22dc883d88..04880b77fb18f3de88c9642bff70eb3cdb0c2dea 100644 |
| --- a/chrome/browser/android/offline_pages/background_loader_offliner.cc |
| +++ b/chrome/browser/android/offline_pages/background_loader_offliner.cc |
| @@ -18,6 +18,10 @@ |
| namespace offline_pages { |
| +namespace { |
| +long kOfflinePageDelayMs = 2000; |
| +} // namespace |
| + |
| BackgroundLoaderOffliner::BackgroundLoaderOffliner( |
| content::BrowserContext* browser_context, |
| const OfflinerPolicy* policy, |
| @@ -94,6 +98,9 @@ bool BackgroundLoaderOffliner::LoadAndSave(const SavePageRequest& request, |
| if (!loader_) |
| ResetState(); |
| + // Invalidate ptrs for all delayed/saving tasks. |
| + weak_ptr_factory_.InvalidateWeakPtrs(); |
| + |
| // Track copy of pending request. |
| pending_request_.reset(new SavePageRequest(request)); |
| completion_callback_ = callback; |
| @@ -129,40 +136,15 @@ void BackgroundLoaderOffliner::DidStopLoading() { |
| return; |
| } |
| - SavePageRequest request(*pending_request_.get()); |
| - // If there was an error navigating to page, return loading failed. |
| - if (page_load_state_ != SUCCESS) { |
| - Offliner::RequestStatus status = |
| - (page_load_state_ == RETRIABLE) |
| - ? Offliner::RequestStatus::LOADING_FAILED |
| - : Offliner::RequestStatus::LOADING_FAILED_NO_RETRY; |
| - completion_callback_.Run(request, status); |
| - ResetState(); |
| - return; |
| - } |
| - |
| - save_state_ = SAVING; |
| - content::WebContents* web_contents( |
| - content::WebContentsObserver::web_contents()); |
| - |
| - std::unique_ptr<OfflinePageArchiver> archiver( |
| - new OfflinePageMHTMLArchiver(web_contents)); |
| + // Invalidate ptrs for any ongoing save operation. |
| + weak_ptr_factory_.InvalidateWeakPtrs(); |
| - OfflinePageModel::SavePageParams params; |
| - params.url = web_contents->GetLastCommittedURL(); |
| - params.client_id = request.client_id(); |
| - params.proposed_offline_id = request.request_id(); |
| - params.is_background = true; |
| - |
| - // Pass in the original URL if it's different from last committed |
| - // when redirects occur. |
| - if (params.url != request.url()) |
| - params.original_url = request.url(); |
| - |
| - offline_page_model_->SavePage( |
| - params, std::move(archiver), |
| - base::Bind(&BackgroundLoaderOffliner::OnPageSaved, |
| - weak_ptr_factory_.GetWeakPtr())); |
| + // Post SavePage task with 2 second delay. |
| + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| + FROM_HERE, |
| + base::Bind(&BackgroundLoaderOffliner::SavePage, |
| + weak_ptr_factory_.GetWeakPtr()), |
| + base::TimeDelta::FromMilliseconds(kOfflinePageDelayMs)); |
| } |
| void BackgroundLoaderOffliner::RenderProcessGone( |
| @@ -230,6 +212,59 @@ void BackgroundLoaderOffliner::DidFinishNavigation( |
| page_load_state_ = RETRIABLE; |
| } |
| } |
| + |
| + // If the page is not the same, invalidate any pending save tasks. |
| + // |
| + // Downloads or 204/205 response codes do not commit (no new navigation) |
| + // Same-Page (committed) navigations are: |
| + // - reference fragment navigations |
| + // - pushState/replaceState |
| + // - same page history navigation |
| + if (navigation_handle->HasCommitted() && !navigation_handle->IsSamePage()) { |
|
fgorski
2017/02/24 22:12:07
int: drop {}
chili
2017/02/27 22:18:29
Done.
|
| + weak_ptr_factory_.InvalidateWeakPtrs(); |
| + } |
| +} |
| + |
| +void BackgroundLoaderOffliner::SavePage() { |
| + if (!pending_request_.get()) { |
| + DVLOG(1) << "Pending request was cleared during delay."; |
| + return; |
| + } |
| + |
| + SavePageRequest request(*pending_request_.get()); |
| + // If there was an error navigating to page, return loading failed. |
| + if (page_load_state_ != SUCCESS) { |
| + Offliner::RequestStatus status = |
| + (page_load_state_ == RETRIABLE) |
| + ? Offliner::RequestStatus::LOADING_FAILED |
| + : Offliner::RequestStatus::LOADING_FAILED_NO_RETRY; |
| + completion_callback_.Run(request, status); |
| + ResetState(); |
| + return; |
| + } |
| + |
| + save_state_ = SAVING; |
| + content::WebContents* web_contents( |
| + content::WebContentsObserver::web_contents()); |
| + |
| + std::unique_ptr<OfflinePageArchiver> archiver( |
| + new OfflinePageMHTMLArchiver(web_contents)); |
| + |
| + OfflinePageModel::SavePageParams params; |
| + params.url = web_contents->GetLastCommittedURL(); |
| + params.client_id = request.client_id(); |
| + params.proposed_offline_id = request.request_id(); |
| + params.is_background = true; |
| + |
| + // Pass in the original URL if it's different from last committed |
| + // when redirects occur. |
| + if (params.url != request.url()) |
| + params.original_url = request.url(); |
| + |
| + offline_page_model_->SavePage( |
| + params, std::move(archiver), |
| + base::Bind(&BackgroundLoaderOffliner::OnPageSaved, |
| + weak_ptr_factory_.GetWeakPtr())); |
| } |
| void BackgroundLoaderOffliner::OnPageSaved(SavePageResult save_result, |