Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(330)

Side by Side Diff: chrome/browser/android/offline_pages/prerendering_loader.cc

Issue 1968593002: PrerenderingLoader initial integration with PrerenderManager/PrerenderHandle (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: More updates for pasko Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "base/threading/thread_task_runner_handle.h"
10 #include "chrome/browser/profiles/profile.h"
7 #include "content/public/browser/browser_context.h" 11 #include "content/public/browser/browser_context.h"
12 #include "content/public/browser/browser_thread.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::IDLE), browser_context_(browser_context) {
20 adapter_.reset(new PrerenderAdapter(this));
21 }
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) {
20 const LoadPageCallback& callback) { 29 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
21 // TODO(dougarnett): implement. 30 if (!IsIdle()) {
22 return false; 31 DVLOG(1)
32 << "WARNING: Existing request in progress or waiting for StopLoading()";
33 return false;
34 }
35 if (!CanPrerender())
36 return false;
37
38 // Create a WebContents instance to define and hold a SessionStorageNamespace
39 // for this load request.
40 DCHECK(!session_contents_.get());
41 session_contents_.reset(content::WebContents::Create(
42 content::WebContents::CreateParams(browser_context_)));
43 content::SessionStorageNamespace* sessionStorageNamespace =
44 session_contents_->GetController().GetDefaultSessionStorageNamespace();
45 gfx::Size renderWindowSize = session_contents_->GetContainerBounds().size();
46 bool accepted = adapter_->StartPrerender(
47 browser_context_, url, sessionStorageNamespace, renderWindowSize);
48 if (!accepted)
49 return false;
50
51 DCHECK(adapter_->IsActive());
52 callback_ = callback;
53 state_ = State::PENDING;
54 return true;
23 } 55 }
24 56
25 void PrerenderingLoader::StopLoading() { 57 void PrerenderingLoader::StopLoading() {
26 // TODO(dougarnett): implement. 58 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
59 CancelPrerender();
60 }
61
62 bool PrerenderingLoader::CanPrerender() {
63 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
64 return adapter_->CanPrerender();
65 }
66
67 bool PrerenderingLoader::IsIdle() {
68 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
69 return state_ == State::IDLE;
70 }
71
72 bool PrerenderingLoader::IsLoaded() {
73 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
74 return state_ == State::LOADED;
75 }
76
77 void PrerenderingLoader::SetAdapterForTesting(
78 std::unique_ptr<PrerenderAdapter> prerender_adapter) {
79 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
80 adapter_ = std::move(prerender_adapter);
81 }
82
83 void PrerenderingLoader::OnPrerenderStart() {
84 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
85 DCHECK(state_ == State::PENDING);
86 state_ = State::LOADING;
87 }
88
89 void PrerenderingLoader::OnPrerenderStopLoading() {
90 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
91 // TODO(dougarnett): Implement/integrate to delay policy here.
92 HandleLoadEvent();
93 }
94
95 void PrerenderingLoader::OnPrerenderDomContentLoaded() {
96 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
97 // TODO(dougarnett): Implement/integrate to delay policy here.
98 HandleLoadEvent();
99 }
100
101 void PrerenderingLoader::OnPrerenderStop() {
102 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
103 HandleLoadingStopped();
104 }
105
106 void PrerenderingLoader::HandleLoadEvent() {
107 // If still loading, check if the load succeeded or not, then update
108 // the internal state (LOADED for success or IDLE for failure) and post
109 // callback.
110 // Note: it is possible to receive a load event (e.g., if timeout-based)
111 // after the request has completed via another path (e.g., canceled) so
112 // the Loader may be idle at this point.
113 if (!IsLoaded() && !IsIdle()) {
pasko 2016/05/23 20:05:41 Less nesting an less negation seems more readable:
dougarnett 2016/05/23 21:43:54 Done.
114 content::WebContents* contents = adapter_->GetWebContents();
115 if (contents) {
116 state_ = State::LOADED;
117 base::ThreadTaskRunnerHandle::Get()->PostTask(
118 FROM_HERE,
119 base::Bind(callback_, Offliner::RequestStatus::LOADED, contents));
120 } else {
121 // No WebContents means that the load failed (and it stopped).
122 HandleLoadingStopped();
123 }
124 }
125 }
126
127 void PrerenderingLoader::HandleLoadingStopped() {
128 // Loading has stopped so unless the Loader has already transistioned to the
129 // idle state, clean up the previous request state, transition to the idle
130 // state, and post callback.
131 // Note: it is possible to receive some asynchronous stopped indication after
132 // the request has completed/stopped via another path so the Loader may be
133 // idle at this point.
134 if (!IsIdle()) {
135 if (adapter_->IsActive()) {
136 DVLOG(1) << "Load failed: " << adapter_->GetFinalStatus();
137 adapter_->DestroyActive();
138 }
139 // Request status depends on whether we are still loading (failed) or
140 // did load and then loading was stopped (cancel - from prerender stack).
141 Offliner::RequestStatus request_status =
142 IsLoaded() ? Offliner::RequestStatus::CANCELED
143 : Offliner::RequestStatus::FAILED;
144 // TODO(dougarnett): For failure, determine from final status if retry-able
145 // and report different failure statuses if retry-able or not.
146 session_contents_.reset(nullptr);
147 state_ = State::IDLE;
148 base::ThreadTaskRunnerHandle::Get()->PostTask(
149 FROM_HERE, base::Bind(callback_, request_status, nullptr));
150 }
151 }
152
153 void PrerenderingLoader::CancelPrerender() {
154 if (adapter_->IsActive()) {
155 adapter_->DestroyActive();
156 }
157 session_contents_.reset(nullptr);
158 if (!IsLoaded() && !IsIdle()) {
159 base::ThreadTaskRunnerHandle::Get()->PostTask(
160 FROM_HERE,
161 base::Bind(callback_, Offliner::RequestStatus::CANCELED, nullptr));
162 }
163 state_ = State::IDLE;
27 } 164 }
28 165
29 } // namespace offline_pages 166 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698