OLD | NEW |
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 Loading... |
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; |
175 if (source_render_view_host) { | 176 if (source_render_view_host) { |
176 DCHECK(source_render_view_host->view() != NULL); | 177 DCHECK(source_render_view_host->view() != NULL); |
177 TabContents* source_tc = | 178 TabContents* source_tc = |
178 source_render_view_host->delegate()->GetAsTabContents(); | 179 source_render_view_host->delegate()->GetAsTabContents(); |
179 if (source_tc) { | 180 if (source_tc) { |
180 // So that history merging will work, get the max page ID | 181 // So that history merging will work, get the max page ID |
181 // of the old page as a starting id. | 182 // of the old page as a starting id. |
182 starting_page_id_ = source_tc->GetMaxPageID(); | 183 starting_page_id_ = source_tc->GetMaxPageID(); |
183 | 184 |
184 // Set the size of the new TC to that of the old TC. | 185 // Set the size of the new TC to that of the old TC. |
185 source_tc->view()->GetContainerBounds(&tab_bounds_); | 186 source_tc->view()->GetContainerBounds(&tab_bounds); |
186 } | 187 } |
187 } else { | 188 } else { |
188 int max_page_id = -1; | 189 int max_page_id = -1; |
189 // Get the largest page ID of all open tabs as a starting id. | 190 // Get the largest page ID of all open tabs as a starting id. |
190 for (BrowserList::BrowserVector::const_iterator browser_iter = | 191 for (BrowserList::BrowserVector::const_iterator browser_iter = |
191 BrowserList::begin(); | 192 BrowserList::begin(); |
192 browser_iter != BrowserList::end(); | 193 browser_iter != BrowserList::end(); |
193 ++browser_iter) { | 194 ++browser_iter) { |
194 const Browser* browser = *browser_iter; | 195 const Browser* browser = *browser_iter; |
195 int num_tabs = browser->tab_count(); | 196 int num_tabs = browser->tab_count(); |
196 for (int tab_index = 0; tab_index < num_tabs; ++tab_index) { | 197 for (int tab_index = 0; tab_index < num_tabs; ++tab_index) { |
197 TabContents* tab_contents = browser->GetTabContentsAt(tab_index); | 198 TabContents* tab_contents = browser->GetTabContentsAt(tab_index); |
198 if (tab_contents != NULL) | 199 if (tab_contents != NULL) |
199 max_page_id = std::max(max_page_id, tab_contents->GetMaxPageID()); | 200 max_page_id = std::max(max_page_id, tab_contents->GetMaxPageID()); |
200 } | 201 } |
201 } | 202 } |
202 starting_page_id_ = max_page_id; | 203 starting_page_id_ = max_page_id; |
203 | 204 |
204 // Try to get the active tab of the active browser and use that for tab | 205 // Try to get the active tab of the active browser and use that for tab |
205 // bounds. If the browser has never been active, we will fail to get a size | 206 // bounds. If the browser has never been active, we will fail to get a size |
206 // but we shouldn't be prerendering in that case anyway. | 207 // but we shouldn't be prerendering in that case anyway. |
207 Browser* active_browser = BrowserList::GetLastActive(); | 208 Browser* active_browser = BrowserList::GetLastActive(); |
208 if (active_browser) { | 209 if (active_browser) { |
209 TabContents* active_tab_contents = active_browser->GetTabContentsAt( | 210 TabContents* active_tab_contents = active_browser->GetTabContentsAt( |
210 active_browser->active_index()); | 211 active_browser->active_index()); |
211 active_tab_contents->view()->GetContainerBounds(&tab_bounds_); | 212 active_tab_contents->view()->GetContainerBounds(&tab_bounds); |
212 } | 213 } |
213 } | 214 } |
214 | 215 |
215 // Add a safety margin of kPrerenderPageIdOffset to the starting page id (for | 216 // Add a safety margin of kPrerenderPageIdOffset to the starting page id (for |
216 // things such as redirects). | 217 // things such as redirects). |
217 if (starting_page_id_ < 0) | 218 if (starting_page_id_ < 0) |
218 starting_page_id_ = 0; | 219 starting_page_id_ = 0; |
219 starting_page_id_ += kPrerenderPageIdOffset; | 220 starting_page_id_ += kPrerenderPageIdOffset; |
220 prerender_contents_->controller().set_max_restored_page_id(starting_page_id_); | 221 prerender_contents_->controller().set_max_restored_page_id(starting_page_id_); |
221 | 222 |
222 tab_contents_delegate_.reset(new TabContentsDelegateImpl(this)); | 223 tab_contents_delegate_.reset(new TabContentsDelegateImpl(this)); |
223 new_contents->set_delegate(tab_contents_delegate_.get()); | 224 new_contents->set_delegate(tab_contents_delegate_.get()); |
224 | 225 |
| 226 // Set the size of the prerender TabContents. |
| 227 prerender_contents_->view()->SizeContents(tab_bounds.size()); |
| 228 |
225 // Register as an observer of the RenderViewHost so we get messages. | 229 // Register as an observer of the RenderViewHost so we get messages. |
226 render_view_host_observer_.reset( | 230 render_view_host_observer_.reset( |
227 new PrerenderRenderViewHostObserver(this, render_view_host_mutable())); | 231 new PrerenderRenderViewHostObserver(this, render_view_host_mutable())); |
228 | 232 |
229 child_id_ = render_view_host()->process()->id(); | 233 child_id_ = render_view_host()->process()->id(); |
230 route_id_ = render_view_host()->routing_id(); | 234 route_id_ = render_view_host()->routing_id(); |
231 | 235 |
232 // Register this with the ResourceDispatcherHost as a prerender | 236 // Register this with the ResourceDispatcherHost as a prerender |
233 // RenderViewHost. This must be done before the Navigate message to catch all | 237 // RenderViewHost. This must be done before the Navigate message to catch all |
234 // resource requests, but as it is on the same thread as the Navigate message | 238 // resource requests, but as it is on the same thread as the Navigate message |
(...skipping 12 matching lines...) Expand all Loading... |
247 // APP_TERMINATING before non-OTR profiles are destroyed). | 251 // APP_TERMINATING before non-OTR profiles are destroyed). |
248 // TODO(tburkard): figure out if this is needed. | 252 // TODO(tburkard): figure out if this is needed. |
249 notification_registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, | 253 notification_registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, |
250 Source<Profile>(profile_)); | 254 Source<Profile>(profile_)); |
251 | 255 |
252 // Register to inform new RenderViews that we're prerendering. | 256 // Register to inform new RenderViews that we're prerendering. |
253 notification_registrar_.Add( | 257 notification_registrar_.Add( |
254 this, content::NOTIFICATION_RENDER_VIEW_HOST_CREATED_FOR_TAB, | 258 this, content::NOTIFICATION_RENDER_VIEW_HOST_CREATED_FOR_TAB, |
255 Source<TabContents>(new_contents)); | 259 Source<TabContents>(new_contents)); |
256 | 260 |
| 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 |
257 // Register for redirect notifications sourced from |this|. | 267 // Register for redirect notifications sourced from |this|. |
258 notification_registrar_.Add( | 268 notification_registrar_.Add( |
259 this, content::NOTIFICATION_RESOURCE_RECEIVED_REDIRECT, | 269 this, content::NOTIFICATION_RESOURCE_RECEIVED_REDIRECT, |
260 Source<RenderViewHostDelegate>(GetRenderViewHostDelegate())); | 270 Source<RenderViewHostDelegate>(GetRenderViewHostDelegate())); |
261 | 271 |
262 // Register for new windows from any source. | 272 // Register for new windows from any source. |
263 notification_registrar_.Add( | 273 notification_registrar_.Add( |
264 this, content::NOTIFICATION_CREATING_NEW_WINDOW_CANCELLED, | 274 this, content::NOTIFICATION_CREATING_NEW_WINDOW_CANCELLED, |
265 Source<TabContents>(new_contents)); | 275 Source<TabContents>(new_contents)); |
266 | 276 |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 | 374 |
365 // When a new RenderView is created for a prerendering TabContents, | 375 // When a new RenderView is created for a prerendering TabContents, |
366 // tell the new RenderView it's being used for prerendering before any | 376 // tell the new RenderView it's being used for prerendering before any |
367 // navigations occur. Note that this is always triggered before the | 377 // navigations occur. Note that this is always triggered before the |
368 // first navigation, so there's no need to send the message just after | 378 // first navigation, so there's no need to send the message just after |
369 // the TabContents is created. | 379 // the TabContents is created. |
370 new_render_view_host->Send( | 380 new_render_view_host->Send( |
371 new ChromeViewMsg_SetIsPrerendering( | 381 new ChromeViewMsg_SetIsPrerendering( |
372 new_render_view_host->routing_id(), | 382 new_render_view_host->routing_id(), |
373 true)); | 383 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. | |
378 prerender_contents_->view()->SizeContents(tab_bounds_.size()); | |
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(); | |
383 } | 384 } |
384 break; | 385 break; |
385 } | 386 } |
386 | 387 |
| 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 |
387 case content::NOTIFICATION_CREATING_NEW_WINDOW_CANCELLED: { | 400 case content::NOTIFICATION_CREATING_NEW_WINDOW_CANCELLED: { |
388 if (prerender_contents_.get()) { | 401 if (prerender_contents_.get()) { |
389 CHECK(Source<TabContents>(source).ptr() == | 402 CHECK(Source<TabContents>(source).ptr() == |
390 prerender_contents_->tab_contents()); | 403 prerender_contents_->tab_contents()); |
391 // Since we don't want to permit child windows that would have a | 404 // Since we don't want to permit child windows that would have a |
392 // window.opener property, terminate prerendering. | 405 // window.opener property, terminate prerendering. |
393 Destroy(FINAL_STATUS_CREATE_NEW_WINDOW); | 406 Destroy(FINAL_STATUS_CREATE_NEW_WINDOW); |
394 } | 407 } |
395 break; | 408 break; |
396 } | 409 } |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
605 bool PrerenderContents::IsCrossSiteNavigationPending() const { | 618 bool PrerenderContents::IsCrossSiteNavigationPending() const { |
606 if (!prerender_contents_.get() || !prerender_contents_->tab_contents()) | 619 if (!prerender_contents_.get() || !prerender_contents_->tab_contents()) |
607 return false; | 620 return false; |
608 const TabContents* tab_contents = prerender_contents_->tab_contents(); | 621 const TabContents* tab_contents = prerender_contents_->tab_contents(); |
609 return (tab_contents->GetSiteInstance() != | 622 return (tab_contents->GetSiteInstance() != |
610 tab_contents->GetPendingSiteInstance()); | 623 tab_contents->GetPendingSiteInstance()); |
611 } | 624 } |
612 | 625 |
613 | 626 |
614 } // namespace prerender | 627 } // namespace prerender |
OLD | NEW |