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; | |
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 Loading... |
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 Loading... |
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. |
| 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(); |
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 Loading... |
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 |
OLD | NEW |