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

Side by Side Diff: chrome/browser/prerender/prerender_contents.cc

Issue 7693029: Deflake PrerenderExcessiveMemory, fix race (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Oops Created 9 years, 3 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/prerender/prerender_contents.h" 5 #include "chrome/browser/prerender/prerender_contents.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/process_util.h" 10 #include "base/process_util.h"
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 DCHECK(profile_ != NULL); 165 DCHECK(profile_ != NULL);
166 DCHECK(!prerendering_has_started_); 166 DCHECK(!prerendering_has_started_);
167 DCHECK(prerender_contents_.get() == NULL); 167 DCHECK(prerender_contents_.get() == NULL);
168 168
169 prerendering_has_started_ = true; 169 prerendering_has_started_ = true;
170 TabContents* new_contents = new TabContents(profile_, NULL, MSG_ROUTING_NONE, 170 TabContents* new_contents = new TabContents(profile_, NULL, MSG_ROUTING_NONE,
171 NULL, NULL); 171 NULL, NULL);
172 prerender_contents_.reset(new TabContentsWrapper(new_contents)); 172 prerender_contents_.reset(new TabContentsWrapper(new_contents));
173 TabContentsObserver::Observe(new_contents); 173 TabContentsObserver::Observe(new_contents);
174 174
175 gfx::Rect tab_bounds;
176 if (source_render_view_host) { 175 if (source_render_view_host) {
177 DCHECK(source_render_view_host->view() != NULL); 176 DCHECK(source_render_view_host->view() != NULL);
178 TabContents* source_tc = 177 TabContents* source_tc =
179 source_render_view_host->delegate()->GetAsTabContents(); 178 source_render_view_host->delegate()->GetAsTabContents();
180 if (source_tc) { 179 if (source_tc) {
181 // So that history merging will work, get the max page ID 180 // So that history merging will work, get the max page ID
182 // of the old page as a starting id. 181 // of the old page as a starting id.
183 starting_page_id_ = source_tc->GetMaxPageID(); 182 starting_page_id_ = source_tc->GetMaxPageID();
184 183
185 // Set the size of the new TC to that of the old TC. 184 // Set the size of the new TC to that of the old TC.
186 source_tc->view()->GetContainerBounds(&tab_bounds); 185 source_tc->view()->GetContainerBounds(&tab_bounds_);
187 } 186 }
188 } else { 187 } else {
189 int max_page_id = -1; 188 int max_page_id = -1;
190 // Get the largest page ID of all open tabs as a starting id. 189 // Get the largest page ID of all open tabs as a starting id.
191 for (BrowserList::BrowserVector::const_iterator browser_iter = 190 for (BrowserList::BrowserVector::const_iterator browser_iter =
192 BrowserList::begin(); 191 BrowserList::begin();
193 browser_iter != BrowserList::end(); 192 browser_iter != BrowserList::end();
194 ++browser_iter) { 193 ++browser_iter) {
195 const Browser* browser = *browser_iter; 194 const Browser* browser = *browser_iter;
196 int num_tabs = browser->tab_count(); 195 int num_tabs = browser->tab_count();
197 for (int tab_index = 0; tab_index < num_tabs; ++tab_index) { 196 for (int tab_index = 0; tab_index < num_tabs; ++tab_index) {
198 TabContents* tab_contents = browser->GetTabContentsAt(tab_index); 197 TabContents* tab_contents = browser->GetTabContentsAt(tab_index);
199 if (tab_contents != NULL) 198 if (tab_contents != NULL)
200 max_page_id = std::max(max_page_id, tab_contents->GetMaxPageID()); 199 max_page_id = std::max(max_page_id, tab_contents->GetMaxPageID());
201 } 200 }
202 } 201 }
203 starting_page_id_ = max_page_id; 202 starting_page_id_ = max_page_id;
204 203
205 // Try to get the active tab of the active browser and use that for tab 204 // Try to get the active tab of the active browser and use that for tab
206 // bounds. If the browser has never been active, we will fail to get a size 205 // bounds. If the browser has never been active, we will fail to get a size
207 // but we shouldn't be prerendering in that case anyway. 206 // but we shouldn't be prerendering in that case anyway.
208 Browser* active_browser = BrowserList::GetLastActive(); 207 Browser* active_browser = BrowserList::GetLastActive();
209 if (active_browser) { 208 if (active_browser) {
210 TabContents* active_tab_contents = active_browser->GetTabContentsAt( 209 TabContents* active_tab_contents = active_browser->GetTabContentsAt(
211 active_browser->active_index()); 210 active_browser->active_index());
212 active_tab_contents->view()->GetContainerBounds(&tab_bounds); 211 active_tab_contents->view()->GetContainerBounds(&tab_bounds_);
213 } 212 }
214 } 213 }
215 214
216 // Add a safety margin of kPrerenderPageIdOffset to the starting page id (for 215 // Add a safety margin of kPrerenderPageIdOffset to the starting page id (for
217 // things such as redirects). 216 // things such as redirects).
218 if (starting_page_id_ < 0) 217 if (starting_page_id_ < 0)
219 starting_page_id_ = 0; 218 starting_page_id_ = 0;
220 starting_page_id_ += kPrerenderPageIdOffset; 219 starting_page_id_ += kPrerenderPageIdOffset;
221 prerender_contents_->controller().set_max_restored_page_id(starting_page_id_); 220 prerender_contents_->controller().set_max_restored_page_id(starting_page_id_);
222 221
223 tab_contents_delegate_.reset(new TabContentsDelegateImpl(this)); 222 tab_contents_delegate_.reset(new TabContentsDelegateImpl(this));
224 new_contents->set_delegate(tab_contents_delegate_.get()); 223 new_contents->set_delegate(tab_contents_delegate_.get());
225 224
226 // Set the size of the prerender TabContents.
227 prerender_contents_->view()->SizeContents(tab_bounds.size());
228
229 // Register as an observer of the RenderViewHost so we get messages. 225 // Register as an observer of the RenderViewHost so we get messages.
230 render_view_host_observer_.reset( 226 render_view_host_observer_.reset(
231 new PrerenderRenderViewHostObserver(this, render_view_host_mutable())); 227 new PrerenderRenderViewHostObserver(this, render_view_host_mutable()));
232 228
233 child_id_ = render_view_host()->process()->id(); 229 child_id_ = render_view_host()->process()->id();
234 route_id_ = render_view_host()->routing_id(); 230 route_id_ = render_view_host()->routing_id();
235 231
236 // Register this with the ResourceDispatcherHost as a prerender 232 // Register this with the ResourceDispatcherHost as a prerender
237 // RenderViewHost. This must be done before the Navigate message to catch all 233 // RenderViewHost. This must be done before the Navigate message to catch all
238 // resource requests, but as it is on the same thread as the Navigate message 234 // resource requests, but as it is on the same thread as the Navigate message
(...skipping 12 matching lines...) Expand all
251 // APP_TERMINATING before non-OTR profiles are destroyed). 247 // APP_TERMINATING before non-OTR profiles are destroyed).
252 // TODO(tburkard): figure out if this is needed. 248 // TODO(tburkard): figure out if this is needed.
253 notification_registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, 249 notification_registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
254 Source<Profile>(profile_)); 250 Source<Profile>(profile_));
255 251
256 // Register to inform new RenderViews that we're prerendering. 252 // Register to inform new RenderViews that we're prerendering.
257 notification_registrar_.Add( 253 notification_registrar_.Add(
258 this, content::NOTIFICATION_RENDER_VIEW_HOST_CREATED_FOR_TAB, 254 this, content::NOTIFICATION_RENDER_VIEW_HOST_CREATED_FOR_TAB,
259 Source<TabContents>(new_contents)); 255 Source<TabContents>(new_contents));
260 256
261 // Register to be told when the RenderView is ready, so we can hide it.
262 // It will automatically be set to visible when we resize it, otherwise.
263 notification_registrar_.Add(this,
264 content::NOTIFICATION_TAB_CONTENTS_CONNECTED,
265 Source<TabContents>(new_contents));
266
267 // Register for redirect notifications sourced from |this|. 257 // Register for redirect notifications sourced from |this|.
268 notification_registrar_.Add( 258 notification_registrar_.Add(
269 this, content::NOTIFICATION_RESOURCE_RECEIVED_REDIRECT, 259 this, content::NOTIFICATION_RESOURCE_RECEIVED_REDIRECT,
270 Source<RenderViewHostDelegate>(GetRenderViewHostDelegate())); 260 Source<RenderViewHostDelegate>(GetRenderViewHostDelegate()));
271 261
272 // Register for new windows from any source. 262 // Register for new windows from any source.
273 notification_registrar_.Add( 263 notification_registrar_.Add(
274 this, content::NOTIFICATION_CREATING_NEW_WINDOW_CANCELLED, 264 this, content::NOTIFICATION_CREATING_NEW_WINDOW_CANCELLED,
275 Source<TabContents>(new_contents)); 265 Source<TabContents>(new_contents));
276 266
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 364
375 // When a new RenderView is created for a prerendering TabContents, 365 // When a new RenderView is created for a prerendering TabContents,
376 // tell the new RenderView it's being used for prerendering before any 366 // tell the new RenderView it's being used for prerendering before any
377 // navigations occur. Note that this is always triggered before the 367 // navigations occur. Note that this is always triggered before the
378 // first navigation, so there's no need to send the message just after 368 // first navigation, so there's no need to send the message just after
379 // the TabContents is created. 369 // the TabContents is created.
380 new_render_view_host->Send( 370 new_render_view_host->Send(
381 new ChromeViewMsg_SetIsPrerendering( 371 new ChromeViewMsg_SetIsPrerendering(
382 new_render_view_host->routing_id(), 372 new_render_view_host->routing_id(),
383 true)); 373 true));
374
375 // Set the size of the prerender TabContents. This must be done after
376 // the RenderView has been created so that the RenderView will be
377 // informated promptly of the size change.
cbentzel 2011/08/29 12:26:18 Nit: informed
378 prerender_contents_->view()->SizeContents(tab_bounds_.size());
cbentzel 2011/08/29 12:26:18 Is the RenderWidgetHostView hidden at this point?
mmenke 2011/08/29 12:30:35 RenderWidgetHostViews start out as visible. This
379
380 // Hide the tab contents. Must be done after setting the size, as
381 // resizing currently forces the RenderView to set itself as visible.
382 prerender_contents_->tab_contents()->HideContents();
384 } 383 }
385 break; 384 break;
386 } 385 }
387 386
388 case content::NOTIFICATION_TAB_CONTENTS_CONNECTED: {
389 if (prerender_contents_.get()) {
390 DCHECK_EQ(Source<TabContents>(source).ptr(),
391 prerender_contents_->tab_contents());
392 // Set the new TabContents and its RenderViewHost as hidden, to reduce
393 // resource usage. This can only be done after the size has been sent
394 // to the RenderView, which is why it's done here.
395 prerender_contents_->tab_contents()->HideContents();
396 }
397 return;
398 }
399
400 case content::NOTIFICATION_CREATING_NEW_WINDOW_CANCELLED: { 387 case content::NOTIFICATION_CREATING_NEW_WINDOW_CANCELLED: {
401 if (prerender_contents_.get()) { 388 if (prerender_contents_.get()) {
402 CHECK(Source<TabContents>(source).ptr() == 389 CHECK(Source<TabContents>(source).ptr() ==
403 prerender_contents_->tab_contents()); 390 prerender_contents_->tab_contents());
404 // Since we don't want to permit child windows that would have a 391 // Since we don't want to permit child windows that would have a
405 // window.opener property, terminate prerendering. 392 // window.opener property, terminate prerendering.
406 Destroy(FINAL_STATUS_CREATE_NEW_WINDOW); 393 Destroy(FINAL_STATUS_CREATE_NEW_WINDOW);
407 } 394 }
408 break; 395 break;
409 } 396 }
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 bool PrerenderContents::IsCrossSiteNavigationPending() const { 605 bool PrerenderContents::IsCrossSiteNavigationPending() const {
619 if (!prerender_contents_.get() || !prerender_contents_->tab_contents()) 606 if (!prerender_contents_.get() || !prerender_contents_->tab_contents())
620 return false; 607 return false;
621 const TabContents* tab_contents = prerender_contents_->tab_contents(); 608 const TabContents* tab_contents = prerender_contents_->tab_contents();
622 return (tab_contents->GetSiteInstance() != 609 return (tab_contents->GetSiteInstance() !=
623 tab_contents->GetPendingSiteInstance()); 610 tab_contents->GetPendingSiteInstance());
624 } 611 }
625 612
626 613
627 } // namespace prerender 614 } // namespace prerender
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698