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" | |
| 8 #include "base/logging.h" | |
| 9 #include "chrome/browser/prerender/prerender_manager.h" | |
| 10 #include "chrome/browser/prerender/prerender_manager_factory.h" | |
| 11 #include "chrome/browser/profiles/profile.h" | |
| 7 #include "content/public/browser/browser_context.h" | 12 #include "content/public/browser/browser_context.h" |
| 8 #include "content/public/browser/web_contents.h" | 13 #include "content/public/browser/web_contents.h" |
| 9 #include "ui/gfx/geometry/size.h" | 14 #include "ui/gfx/geometry/size.h" |
| 10 | 15 |
| 11 namespace offline_pages { | 16 namespace offline_pages { |
| 12 | 17 |
| 13 PrerenderingLoader::PrerenderingLoader( | 18 PrerenderingLoader::PrerenderingLoader(content::BrowserContext* browser_context) |
| 14 content::BrowserContext* browser_context) {} | 19 : state_(State::kIdle), |
| 20 browser_context_(browser_context), | |
| 21 adapter_(new PrerenderAdapter()) {} | |
| 15 | 22 |
| 16 PrerenderingLoader::~PrerenderingLoader() {} | 23 PrerenderingLoader::~PrerenderingLoader() { |
| 24 CancelPrerender(); | |
| 25 } | |
| 17 | 26 |
| 18 bool PrerenderingLoader::LoadPage( | 27 bool PrerenderingLoader::LoadPage(const GURL& url, |
| 19 const GURL& url, | 28 const LoadPageCallback& callback) { |
|
pasko
2016/05/12 19:10:07
assert that runs on the correct thread for every m
dougarnett
2016/05/13 00:00:24
Done.
| |
| 20 const LoadPageCallback& callback) { | 29 if (state_ != State::kIdle) { |
| 21 // TODO(dougarnett): implement. | 30 DVLOG(1) << "WARNING: Existing request pending"; |
| 22 return false; | 31 return false; |
| 32 } | |
| 33 if (!CanPrerender()) | |
| 34 return false; | |
| 35 | |
| 36 // Create a WebContents instance to define and hold a SessionStorageNamespace | |
| 37 // for this load request. | |
| 38 DCHECK(!session_contents_.get()); | |
| 39 session_contents_.reset(content::WebContents::Create( | |
| 40 content::WebContents::CreateParams(browser_context_))); | |
| 41 | |
| 42 adapter_->AddPrerenderForOffline( | |
|
pasko
2016/05/12 19:10:07
does not check return value, which can be false in
dougarnett
2016/05/13 00:00:24
Done.
| |
| 43 browser_context_, url, | |
| 44 GetSessionStorageNamespace(session_contents_.get()), | |
| 45 GetSize(session_contents_.get())); | |
| 46 if (!adapter_->IsActive()) | |
| 47 return false; | |
| 48 | |
| 49 callback_ = callback; | |
| 50 adapter_->SetObserver(this); | |
| 51 state_ = State::kLoading; | |
|
pasko
2016/05/12 19:10:07
Though the Google C++ Style Guide now says to use
dougarnett
2016/05/13 00:00:24
Done.
| |
| 52 return true; | |
| 23 } | 53 } |
| 24 | 54 |
| 25 void PrerenderingLoader::StopLoading() { | 55 void PrerenderingLoader::StopLoading() { |
| 26 // TODO(dougarnett): implement. | 56 CancelPrerender(); |
| 57 state_ = State::kIdle; | |
| 58 } | |
| 59 | |
| 60 bool PrerenderingLoader::CanPrerender() { | |
| 61 // First check if prerendering is enabled. | |
| 62 return adapter_->CanPrerender(); | |
| 63 } | |
| 64 | |
| 65 bool PrerenderingLoader::IsIdle() { | |
| 66 return state_ == State::kIdle; | |
| 67 } | |
| 68 | |
| 69 content::SessionStorageNamespace* | |
| 70 PrerenderingLoader::GetSessionStorageNamespace(content::WebContents* contents) { | |
| 71 return contents->GetController().GetDefaultSessionStorageNamespace(); | |
| 72 } | |
| 73 | |
| 74 const gfx::Size PrerenderingLoader::GetSize(content::WebContents* contents) { | |
| 75 return contents->GetContainerBounds().size(); | |
|
pasko
2016/05/12 19:10:07
I suspect the size would be not what we want here,
dougarnett
2016/05/13 00:00:24
Any idea on how to determine it if no Tab context
dougarnett
2016/05/16 23:51:38
Egor, still open question for alternative.
| |
| 76 } | |
| 77 | |
| 78 void PrerenderingLoader::ReportLoaded() { | |
| 79 if (state_ == State::kLoading) { | |
| 80 content::WebContents* contents = adapter_->GetWebContents(); | |
| 81 if (contents) { | |
| 82 state_ = State::kLoaded; | |
| 83 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
|
pasko
2016/05/12 19:10:07
why ThreadTaskRunnerHandle? Can this just call the
dougarnett
2016/05/13 00:00:24
This one probably could. The PostTask was added pe
| |
| 84 FROM_HERE, | |
| 85 base::Bind(callback_, Offliner::CompletionStatus::LOADED, contents)); | |
| 86 } else { | |
| 87 ReportLoadFailed(); | |
| 88 } | |
| 89 } | |
| 90 } | |
| 91 | |
| 92 void PrerenderingLoader::ReportLoadFailed() { | |
| 93 if (state_ != State::kLoaded && state_ != State::kIdle) { | |
| 94 if (adapter_->IsActive()) | |
| 95 DVLOG(1) << "Load failed: " << adapter_->GetFinalStatus(); | |
| 96 // TODO(dougarnett): Determine from final status if retry-able. | |
| 97 state_ = State::kIdle; | |
| 98 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 99 FROM_HERE, | |
| 100 base::Bind(callback_, Offliner::CompletionStatus::FAILED_CONSIDER_RETRY, | |
|
pasko
2016/05/12 19:10:07
should we assume non-retriable by default and retr
dougarnett
2016/05/13 00:00:24
Done.
| |
| 101 nullptr)); | |
| 102 } | |
| 103 } | |
| 104 | |
| 105 void PrerenderingLoader::CancelPrerender() { | |
| 106 if (adapter_->IsActive()) { | |
| 107 adapter_->OnCancel(); | |
| 108 adapter_->DestroyActive(); | |
| 109 } | |
| 110 session_contents_.reset(nullptr); | |
|
pasko
2016/05/12 19:10:07
we should run the callback here
dougarnett
2016/05/13 00:00:24
Done.
| |
| 111 } | |
| 112 | |
| 113 void PrerenderingLoader::OnPrerenderStart(prerender::PrerenderHandle* handle) { | |
| 114 if (adapter_->IsActive(handle) && state_ == State::kPending) { | |
| 115 state_ = State::kLoading; | |
| 116 } | |
| 117 } | |
| 118 | |
| 119 void PrerenderingLoader::OnPrerenderStopLoading( | |
| 120 prerender::PrerenderHandle* handle) { | |
| 121 if (adapter_->IsActive(handle)) { | |
| 122 // TODO(dougarnett): Implement/integrate to delay policy here. | |
| 123 ReportLoaded(); | |
| 124 } | |
| 125 } | |
| 126 | |
| 127 void PrerenderingLoader::OnPrerenderDomContentLoaded( | |
| 128 prerender::PrerenderHandle* handle) { | |
| 129 if (adapter_->IsActive(handle)) { | |
| 130 // TODO(dougarnett): Implement/integrate to delay policy here. | |
| 131 ReportLoaded(); | |
| 132 } | |
| 133 } | |
| 134 | |
| 135 void PrerenderingLoader::OnPrerenderStop(prerender::PrerenderHandle* handle) { | |
| 136 if (adapter_->IsActive(handle)) { | |
| 137 ReportLoadFailed(); | |
| 138 } | |
| 139 } | |
| 140 | |
| 141 void PrerenderingLoader::SetAdapterForTesting( | |
|
pasko
2016/05/12 19:10:07
the order of methods in the .cc file should match
dougarnett
2016/05/13 00:00:24
Done.
| |
| 142 PrerenderAdapter* prerender_adapter) { | |
| 143 adapter_.reset(prerender_adapter); | |
| 27 } | 144 } |
| 28 | 145 |
| 29 } // namespace offline_pages | 146 } // namespace offline_pages |
| OLD | NEW |