Chromium Code Reviews| Index: chrome/browser/android/offline_pages/prerendering_offliner.cc |
| diff --git a/chrome/browser/android/offline_pages/prerendering_offliner.cc b/chrome/browser/android/offline_pages/prerendering_offliner.cc |
| index b654c75a6b5620ebe6bf03e7d525daa88a111cb0..42c5675db5fe899cbe4e4b138e166db1690d3f25 100644 |
| --- a/chrome/browser/android/offline_pages/prerendering_offliner.cc |
| +++ b/chrome/browser/android/offline_pages/prerendering_offliner.cc |
| @@ -5,6 +5,7 @@ |
| #include "chrome/browser/android/offline_pages/prerendering_offliner.h" |
| #include "base/bind.h" |
| +#include "chrome/browser/android/offline_pages/offline_page_mhtml_archiver.h" |
| #include "components/offline_pages/background/save_page_request.h" |
| #include "content/public/browser/browser_context.h" |
| @@ -16,28 +17,86 @@ PrerenderingOffliner::PrerenderingOffliner( |
| OfflinePageModel* offline_page_model) |
| : browser_context_(browser_context), |
| offline_page_model_(offline_page_model), |
| - weak_ptr_factory_(this) {} |
| + weak_ptr_factory_(this), |
| + pending_request_id_(0) {} |
| PrerenderingOffliner::~PrerenderingOffliner() {} |
| -void PrerenderingOffliner::OnLoadPageDone(Offliner::RequestStatus load_status, |
| - content::WebContents* contents) { |
| - // TODO(dougarnett): Implement save attempt and running CompletionCallback. |
| +void PrerenderingOffliner::OnLoadPageDone( |
| + const SavePageRequest& request, |
| + const CompletionCallback& completion_callback, |
| + Offliner::RequestStatus load_status, |
| + content::WebContents* web_contents) { |
| + // Check if request is still pending receiving a callback. |
| + // Note: it is possible to get a loaded page, start the save operation, |
| + // and then get another callback from the Loader (eg, if its loaded |
| + // WebContents is being destroyed for some resource reclamation). |
| + if (request.request_id() != pending_request_id_) |
|
Pete Williamson
2016/05/24 00:40:07
So if this happens, it looks like the request is i
dougarnett
2016/05/24 19:07:26
The callback is ignored because the request has al
Pete Williamson
2016/05/24 21:18:41
OK, per our discussion, maybe add more DCHECKs to
dougarnett
2016/05/25 18:04:19
Reworked to keep ptr to pending request - hopefull
|
| + return; |
| + |
| + if (load_status == Offliner::RequestStatus::LOADED) { |
| + // Page is loaded so now attempt to save it. We next are waiting for |
| + // callback to this save request or may get cancel callback from the |
| + // Loader (if this loaded web_contents is being reclaimed). |
|
Pete Williamson
2016/05/24 00:40:07
This sentence is a bit strangely worded, please cl
dougarnett
2016/05/24 19:07:26
I agree - please check new wording
Pete Williamson
2016/05/24 21:18:42
New wording is OK.
dougarnett
2016/05/25 18:04:19
Acknowledged.
|
| + DCHECK(web_contents); |
| + std::unique_ptr<OfflinePageArchiver> archiver( |
| + new OfflinePageMHTMLArchiver(web_contents)); |
| + SavePage(request.url(), request.client_id(), std::move(archiver), |
| + base::Bind(&PrerenderingOffliner::OnSavePageDone, |
| + weak_ptr_factory_.GetWeakPtr(), request, |
|
Pete Williamson
2016/05/24 00:40:07
I normally just have the class inherit publicly fr
dewittj
2016/05/24 17:56:09
It's generally considered bad form to use Supports
dougarnett
2016/05/24 19:07:26
Are we transitioning to that pattern? The GetWeakP
Pete Williamson
2016/05/24 21:18:41
OK, then we should do as Justin suggests.
dougarnett
2016/05/25 18:04:19
Acknowledged.
|
| + completion_callback)); |
| + } else { |
| + // Clear pending request and then run its completion callback. |
|
Pete Williamson
2016/05/24 00:40:07
So does this mean we only get one callback for suc
dougarnett
2016/05/24 19:07:26
Yes, only supporting one save attempt initially. I
Pete Williamson
2016/05/24 21:18:42
Ack.
|
| + ClearPendingRequest(); |
| + completion_callback.Run(request, load_status); |
| + } |
| +} |
| + |
| +void PrerenderingOffliner::OnSavePageDone( |
| + const SavePageRequest& request, |
| + const CompletionCallback& completion_callback, |
| + SavePageResult save_result, |
| + int64_t offline_id) { |
| + // Check if request is still pending receiving a callback. |
| + if (request.request_id() != pending_request_id_) |
| + return; |
| + |
| + Offliner::RequestStatus save_status; |
| + if (save_result == SavePageResult::SUCCESS) { |
| + save_status = RequestStatus::SAVED; |
| + } else { |
| + // TODO(dougarnett): Consider reflecting some recommendation to retry the |
| + // request based on specific save error cases. |
| + save_status = RequestStatus::FAILED_SAVE; |
| + } |
| + ClearPendingRequest(); |
| + completion_callback.Run(request, save_status); |
| } |
| bool PrerenderingOffliner::LoadAndSave(const SavePageRequest& request, |
| const CompletionCallback& callback) { |
| - if (!offline_page_model_->CanSavePage(request.url())) |
| + if (!CanSavePage(request.url())) |
| return false; |
| + // Track pending request for callback handling. This also ensures |
| + // there is no current pending request. |
|
Pete Williamson
2016/05/24 00:40:07
But it only makes sure of that while debugging. D
dougarnett
2016/05/24 19:07:26
Backing off the comment for now. Debug time might
Pete Williamson
2016/05/24 21:18:41
ok
dougarnett
2016/05/25 18:04:19
Revised to return false if already have pending re
|
| + SetPendingRequest(request.request_id()); |
| + |
| // Kick off load page attempt. |
| - return GetOrCreateLoader()->LoadPage( |
| - request.url(), base::Bind(&PrerenderingOffliner::OnLoadPageDone, |
| - weak_ptr_factory_.GetWeakPtr())); |
| + bool accepted = GetOrCreateLoader()->LoadPage( |
| + request.url(), |
| + base::Bind(&PrerenderingOffliner::OnLoadPageDone, |
| + weak_ptr_factory_.GetWeakPtr(), request, callback)); |
|
Pete Williamson
2016/05/24 00:40:07
You can use AsWeakPtr() here too.
Pete Williamson
2016/05/24 21:18:42
Per Justin's comment above, you can ignore this.
|
| + if (!accepted) |
| + ClearPendingRequest(); |
| + |
| + return accepted; |
| } |
| void PrerenderingOffliner::Cancel() { |
| + ClearPendingRequest(); |
| GetOrCreateLoader()->StopLoading(); |
| + // TODO(dougarnett): Consider ability to cancel SavePage request. |
| } |
| void PrerenderingOffliner::SetLoaderForTesting( |
| @@ -46,6 +105,20 @@ void PrerenderingOffliner::SetLoaderForTesting( |
| loader_ = std::move(loader); |
| } |
| +bool PrerenderingOffliner::CanSavePage(const GURL& url) { |
| + DCHECK(offline_page_model_); |
| + return offline_page_model_->CanSavePage(url); |
| +} |
| + |
| +void PrerenderingOffliner::SavePage( |
| + const GURL& url, |
| + const ClientId& client_id, |
| + std::unique_ptr<OfflinePageArchiver> archiver, |
| + const SavePageCallback& callback) { |
| + DCHECK(offline_page_model_); |
| + offline_page_model_->SavePage(url, client_id, std::move(archiver), callback); |
| +} |
| + |
| PrerenderingLoader* PrerenderingOffliner::GetOrCreateLoader() { |
| if (!loader_) { |
| loader_.reset(new PrerenderingLoader(browser_context_)); |
| @@ -53,4 +126,15 @@ PrerenderingLoader* PrerenderingOffliner::GetOrCreateLoader() { |
| return loader_.get(); |
| } |
| +void PrerenderingOffliner::SetPendingRequest(int64_t request_id) { |
| + DCHECK_GT(request_id, 0); |
| + DCHECK_EQ(pending_request_id_, 0); |
| + pending_request_id_ = request_id; |
| +} |
| + |
| +void PrerenderingOffliner::ClearPendingRequest() { |
| + DCHECK_GT(pending_request_id_, 0); |
| + pending_request_id_ = 0; |
| +} |
| + |
| } // namespace offline_pages |