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

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

Issue 11348357: Add observer interface to PrerenderContents. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: _really_ fix windows build. Created 8 years 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <functional> 8 #include <functional>
9 #include <utility> 9 #include <utility>
10 10
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 else 66 else
67 message = new PrerenderMsg_RemovePrerenderURL(url); 67 message = new PrerenderMsg_RemovePrerenderURL(url);
68 render_process_host->Send(message); 68 render_process_host->Send(message);
69 } 69 }
70 70
71 } // namespace 71 } // namespace
72 72
73 class PrerenderContentsFactoryImpl : public PrerenderContents::Factory { 73 class PrerenderContentsFactoryImpl : public PrerenderContents::Factory {
74 public: 74 public:
75 virtual PrerenderContents* CreatePrerenderContents( 75 virtual PrerenderContents* CreatePrerenderContents(
76 PrerenderManager* prerender_manager, PrerenderTracker* prerender_tracker, 76 PrerenderManager* prerender_manager, Profile* profile,
77 Profile* profile, const GURL& url, const content::Referrer& referrer, 77 const GURL& url, const content::Referrer& referrer,
78 Origin origin, uint8 experiment_id) OVERRIDE { 78 Origin origin, uint8 experiment_id) OVERRIDE {
79 return new PrerenderContents(prerender_manager, prerender_tracker, profile, 79 return new PrerenderContents(prerender_manager, profile,
80 url, referrer, origin, experiment_id); 80 url, referrer, origin, experiment_id);
81 } 81 }
82 }; 82 };
83 83
84 // TabContentsDelegateImpl ----------------------------------------------------- 84 // TabContentsDelegateImpl -----------------------------------------------------
85 85
86 class PrerenderContents::TabContentsDelegateImpl 86 class PrerenderContents::TabContentsDelegateImpl
87 : public content::WebContentsDelegate { 87 : public content::WebContentsDelegate {
88 public: 88 public:
89 explicit TabContentsDelegateImpl(PrerenderContents* prerender_contents) : 89 explicit TabContentsDelegateImpl(PrerenderContents* prerender_contents) :
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 bool user_gesture) OVERRIDE { 160 bool user_gesture) OVERRIDE {
161 // TODO(mmenke): Consider supporting this if it is a common case during 161 // TODO(mmenke): Consider supporting this if it is a common case during
162 // prerenders. 162 // prerenders.
163 prerender_contents_->Destroy(FINAL_STATUS_REGISTER_PROTOCOL_HANDLER); 163 prerender_contents_->Destroy(FINAL_STATUS_REGISTER_PROTOCOL_HANDLER);
164 } 164 }
165 165
166 private: 166 private:
167 PrerenderContents* prerender_contents_; 167 PrerenderContents* prerender_contents_;
168 }; 168 };
169 169
170 PrerenderContents::Observer::Observer() {
171 }
172
173 PrerenderContents::Observer::~Observer() {
174 }
175
170 PrerenderContents::PendingPrerenderInfo::PendingPrerenderInfo( 176 PrerenderContents::PendingPrerenderInfo::PendingPrerenderInfo(
171 base::WeakPtr<PrerenderHandle> weak_prerender_handle, 177 base::WeakPtr<PrerenderHandle> weak_prerender_handle,
172 Origin origin, 178 Origin origin,
173 const GURL& url, 179 const GURL& url,
174 const content::Referrer& referrer, 180 const content::Referrer& referrer,
175 const gfx::Size& size) : weak_prerender_handle(weak_prerender_handle), 181 const gfx::Size& size) : weak_prerender_handle(weak_prerender_handle),
176 origin(origin), 182 origin(origin),
177 url(url), 183 url(url),
178 referrer(referrer), 184 referrer(referrer),
179 size(size) { 185 size(size) {
(...skipping 15 matching lines...) Expand all
195 prerender_contents_->web_contents()->GetController() 201 prerender_contents_->web_contents()->GetController()
196 .GetDefaultSessionStorageNamespace(); 202 .GetDefaultSessionStorageNamespace();
197 } 203 }
198 prerender_manager_->StartPendingPrerenders( 204 prerender_manager_->StartPendingPrerenders(
199 child_id_, &pending_prerenders_, session_storage_namespace); 205 child_id_, &pending_prerenders_, session_storage_namespace);
200 pending_prerenders_.clear(); 206 pending_prerenders_.clear();
201 } 207 }
202 208
203 PrerenderContents::PrerenderContents( 209 PrerenderContents::PrerenderContents(
204 PrerenderManager* prerender_manager, 210 PrerenderManager* prerender_manager,
205 PrerenderTracker* prerender_tracker,
206 Profile* profile, 211 Profile* profile,
207 const GURL& url, 212 const GURL& url,
208 const content::Referrer& referrer, 213 const content::Referrer& referrer,
209 Origin origin, 214 Origin origin,
210 uint8 experiment_id) 215 uint8 experiment_id)
211 : prerendering_has_started_(false), 216 : prerendering_has_started_(false),
212 prerender_manager_(prerender_manager), 217 prerender_manager_(prerender_manager),
213 prerender_tracker_(prerender_tracker),
214 prerender_url_(url), 218 prerender_url_(url),
215 referrer_(referrer), 219 referrer_(referrer),
216 profile_(profile), 220 profile_(profile),
217 page_id_(0), 221 page_id_(0),
218 session_storage_namespace_id_(-1), 222 session_storage_namespace_id_(-1),
219 has_stopped_loading_(false), 223 has_stopped_loading_(false),
220 has_finished_loading_(false), 224 has_finished_loading_(false),
221 final_status_(FINAL_STATUS_MAX), 225 final_status_(FINAL_STATUS_MAX),
222 match_complete_status_(MATCH_COMPLETE_DEFAULT), 226 match_complete_status_(MATCH_COMPLETE_DEFAULT),
223 prerendering_has_been_cancelled_(false), 227 prerendering_has_been_cancelled_(false),
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 InformRenderProcessAboutPrerender(prerender_url_, true, 281 InformRenderProcessAboutPrerender(prerender_url_, true,
278 creator_child_id_); 282 creator_child_id_);
279 283
280 DCHECK(load_start_time_.is_null()); 284 DCHECK(load_start_time_.is_null());
281 load_start_time_ = base::TimeTicks::Now(); 285 load_start_time_ = base::TimeTicks::Now();
282 286
283 // Everything after this point sets up the WebContents object and associated 287 // Everything after this point sets up the WebContents object and associated
284 // RenderView for the prerender page. Don't do this for members of the 288 // RenderView for the prerender page. Don't do this for members of the
285 // control group. 289 // control group.
286 if (is_control_group) 290 if (is_control_group)
287 return; 291 return;
mmenke 2012/12/06 19:54:22 This is Weird. We use prerender_manager_->IsContr
gavinp 2012/12/07 17:37:04 Done.
288 292
289 prerendering_has_started_ = true; 293 prerendering_has_started_ = true;
290 294
291 WebContents* new_contents = CreateWebContents(session_storage_namespace); 295 WebContents* new_contents = CreateWebContents(session_storage_namespace);
292 prerender_contents_.reset( 296 prerender_contents_.reset(
293 TabContents::Factory::CreateTabContents(new_contents)); 297 TabContents::Factory::CreateTabContents(new_contents));
294 content::WebContentsObserver::Observe(new_contents); 298 content::WebContentsObserver::Observe(new_contents);
295 299
296 tab_contents_delegate_.reset(new TabContentsDelegateImpl(this)); 300 tab_contents_delegate_.reset(new TabContentsDelegateImpl(this));
297 new_contents->SetDelegate(tab_contents_delegate_.get()); 301 new_contents->SetDelegate(tab_contents_delegate_.get());
298 302
299 // Set the size of the prerender WebContents. 303 // Set the size of the prerender WebContents.
300 prerender_contents_->web_contents()->GetView()->SizeContents(size_); 304 prerender_contents_->web_contents()->GetView()->SizeContents(size_);
301 305
302 // Register as an observer of the RenderViewHost so we get messages. 306 // Register as an observer of the RenderViewHost so we get messages.
303 render_view_host_observer_.reset( 307 render_view_host_observer_.reset(
304 new PrerenderRenderViewHostObserver(this, GetRenderViewHostMutable())); 308 new PrerenderRenderViewHostObserver(this, GetRenderViewHostMutable()));
305 309
306 child_id_ = GetRenderViewHost()->GetProcess()->GetID(); 310 child_id_ = GetRenderViewHost()->GetProcess()->GetID();
307 route_id_ = GetRenderViewHost()->GetRoutingID(); 311 route_id_ = GetRenderViewHost()->GetRoutingID();
308 312
309 // Register this with the ResourceDispatcherHost as a prerender 313 // Register this with the ResourceDispatcherHost as a prerender
310 // RenderViewHost. This must be done before the Navigate message to catch all 314 // RenderViewHost. This must be done before the Navigate message to catch all
311 // resource requests, but as it is on the same thread as the Navigate message 315 // resource requests, but as it is on the same thread as the Navigate message
312 // (IO) there is no race condition. 316 // (IO) there is no race condition.
313 prerender_tracker_->OnPrerenderingStarted( 317 AddObserver(prerender_manager()->prerender_tracker());
314 child_id_, 318 NotifyPrerenderStart();
315 route_id_,
316 prerender_manager_);
317 319
318 // Close ourselves when the application is shutting down. 320 // Close ourselves when the application is shutting down.
319 notification_registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, 321 notification_registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING,
320 content::NotificationService::AllSources()); 322 content::NotificationService::AllSources());
321 323
322 // Register for our parent profile to shutdown, so we can shut ourselves down 324 // Register for our parent profile to shutdown, so we can shut ourselves down
323 // as well (should only be called for OTR profiles, as we should receive 325 // as well (should only be called for OTR profiles, as we should receive
324 // APP_TERMINATING before non-OTR profiles are destroyed). 326 // APP_TERMINATING before non-OTR profiles are destroyed).
325 // TODO(tburkard): figure out if this is needed. 327 // TODO(tburkard): figure out if this is needed.
326 notification_registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, 328 notification_registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 return child_id_ != -1; 361 return child_id_ != -1;
360 } 362 }
361 363
362 bool PrerenderContents::GetRouteId(int* route_id) const { 364 bool PrerenderContents::GetRouteId(int* route_id) const {
363 CHECK(route_id); 365 CHECK(route_id);
364 DCHECK_GE(route_id_, -1); 366 DCHECK_GE(route_id_, -1);
365 *route_id = route_id_; 367 *route_id = route_id_;
366 return route_id_ != -1; 368 return route_id_ != -1;
367 } 369 }
368 370
369 void PrerenderContents::set_final_status(FinalStatus final_status) { 371 void PrerenderContents::SetFinalStatus(FinalStatus final_status) {
370 DCHECK(final_status >= FINAL_STATUS_USED && final_status < FINAL_STATUS_MAX); 372 DCHECK(final_status >= FINAL_STATUS_USED && final_status < FINAL_STATUS_MAX);
371 DCHECK(final_status_ == FINAL_STATUS_MAX); 373 DCHECK(final_status_ == FINAL_STATUS_MAX);
372 374
373 final_status_ = final_status; 375 final_status_ = final_status;
376
377 if (!prerender_manager_->IsControlGroup() && prerendering_has_started())
378 NotifyPrerenderStop();
374 } 379 }
375 380
376 PrerenderContents::~PrerenderContents() { 381 PrerenderContents::~PrerenderContents() {
377 DCHECK(final_status_ != FINAL_STATUS_MAX); 382 DCHECK_NE(FINAL_STATUS_MAX, final_status_);
378 DCHECK(prerendering_has_been_cancelled_ || 383 DCHECK(
379 final_status_ == FINAL_STATUS_USED); 384 prerendering_has_been_cancelled_ || final_status_ == FINAL_STATUS_USED);
380 DCHECK(origin_ != ORIGIN_MAX); 385 DCHECK_NE(ORIGIN_MAX, origin_);
381 386
382 prerender_manager_->RecordFinalStatusWithMatchCompleteStatus( 387 prerender_manager_->RecordFinalStatusWithMatchCompleteStatus(
383 origin_, 388 origin_, experiment_id_, match_complete_status_, final_status_);
384 experiment_id_,
385 match_complete_status_,
386 final_status_);
387 389
388 if (child_id_ != -1 && route_id_ != -1) { 390 if (child_id_ != -1 && route_id_ != -1) {
389 prerender_tracker_->OnPrerenderingFinished(child_id_, route_id_);
390 for (std::vector<GURL>::const_iterator it = alias_urls_.begin(); 391 for (std::vector<GURL>::const_iterator it = alias_urls_.begin();
391 it != alias_urls_.end(); 392 it != alias_urls_.end();
392 ++it) { 393 ++it) {
393 InformRenderProcessAboutPrerender(*it, false, creator_child_id_); 394 InformRenderProcessAboutPrerender(*it, false, creator_child_id_);
394 } 395 }
395 } 396 }
396 397
397 // If we still have a WebContents, clean up anything we need to and then 398 // If we still have a WebContents, clean up anything we need to and then
398 // destroy it. 399 // destroy it.
399 if (prerender_contents_.get()) 400 if (prerender_contents_.get())
400 delete ReleasePrerenderContents(); 401 delete ReleasePrerenderContents();
401 } 402 }
402 403
404 void PrerenderContents::AddObserver(Observer* observer) {
405 DCHECK_EQ(FINAL_STATUS_MAX, final_status_);
406 observer_list_.AddObserver(observer);
407 }
408
403 void PrerenderContents::Observe(int type, 409 void PrerenderContents::Observe(int type,
404 const content::NotificationSource& source, 410 const content::NotificationSource& source,
405 const content::NotificationDetails& details) { 411 const content::NotificationDetails& details) {
406 switch (type) { 412 switch (type) {
407 case chrome::NOTIFICATION_PROFILE_DESTROYED: 413 case chrome::NOTIFICATION_PROFILE_DESTROYED:
408 Destroy(FINAL_STATUS_PROFILE_DESTROYED); 414 Destroy(FINAL_STATUS_PROFILE_DESTROYED);
409 return; 415 return;
410 416
411 case chrome::NOTIFICATION_APP_TERMINATING: 417 case chrome::NOTIFICATION_APP_TERMINATING:
412 Destroy(FINAL_STATUS_APP_TERMINATING); 418 Destroy(FINAL_STATUS_APP_TERMINATING);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 WebContents* PrerenderContents::CreateWebContents( 483 WebContents* PrerenderContents::CreateWebContents(
478 SessionStorageNamespace* session_storage_namespace) { 484 SessionStorageNamespace* session_storage_namespace) {
479 // TODO(ajwong): Remove the temporary map once prerendering is aware of 485 // TODO(ajwong): Remove the temporary map once prerendering is aware of
480 // multiple session storage namespaces per tab. 486 // multiple session storage namespaces per tab.
481 content::SessionStorageNamespaceMap session_storage_namespace_map; 487 content::SessionStorageNamespaceMap session_storage_namespace_map;
482 session_storage_namespace_map[""] = session_storage_namespace; 488 session_storage_namespace_map[""] = session_storage_namespace;
483 return WebContents::CreateWithSessionStorage( 489 return WebContents::CreateWithSessionStorage(
484 profile_, NULL, MSG_ROUTING_NONE, NULL, session_storage_namespace_map); 490 profile_, NULL, MSG_ROUTING_NONE, NULL, session_storage_namespace_map);
485 } 491 }
486 492
493 void PrerenderContents::NotifyPrerenderStart() {
494 DCHECK_EQ(FINAL_STATUS_MAX, final_status_);
495 FOR_EACH_OBSERVER(Observer, observer_list_, OnPrerenderStart(this));
496 }
497
498 void PrerenderContents::NotifyPrerenderStop() {
499 DCHECK_NE(FINAL_STATUS_MAX, final_status_);
500 FOR_EACH_OBSERVER(Observer, observer_list_, OnPrerenderStop(this));
501 observer_list_.Clear();
502 }
503
487 void PrerenderContents::OnUpdateFaviconURL( 504 void PrerenderContents::OnUpdateFaviconURL(
488 int32 page_id, 505 int32 page_id,
489 const std::vector<FaviconURL>& urls) { 506 const std::vector<FaviconURL>& urls) {
490 VLOG(1) << "PrerenderContents::OnUpdateFaviconURL" << icon_url_; 507 VLOG(1) << "PrerenderContents::OnUpdateFaviconURL" << icon_url_;
491 for (std::vector<FaviconURL>::const_iterator it = urls.begin(); 508 for (std::vector<FaviconURL>::const_iterator it = urls.begin();
492 it != urls.end(); ++it) { 509 it != urls.end(); ++it) {
493 if (it->icon_type == FaviconURL::FAVICON) { 510 if (it->icon_type == FaviconURL::FAVICON) {
494 icon_url_ = it->icon_url; 511 icon_url_ = it->icon_url;
495 VLOG(1) << icon_url_; 512 VLOG(1) << icon_url_;
496 return; 513 return;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 590
574 void PrerenderContents::Destroy(FinalStatus final_status) { 591 void PrerenderContents::Destroy(FinalStatus final_status) {
575 if (prerendering_has_been_cancelled_) 592 if (prerendering_has_been_cancelled_)
576 return; 593 return;
577 594
578 if (child_id_ != -1 && route_id_ != -1) { 595 if (child_id_ != -1 && route_id_ != -1) {
579 // Cancel the prerender in the PrerenderTracker. This is needed 596 // Cancel the prerender in the PrerenderTracker. This is needed
580 // because destroy may be called directly from the UI thread without calling 597 // because destroy may be called directly from the UI thread without calling
581 // TryCancel(). This is difficult to completely avoid, since prerendering 598 // TryCancel(). This is difficult to completely avoid, since prerendering
582 // can be cancelled before a RenderView is created. 599 // can be cancelled before a RenderView is created.
583 bool is_cancelled = prerender_tracker_->TryCancel( 600 bool is_cancelled = prerender_manager()->prerender_tracker()->TryCancel(
584 child_id_, route_id_, final_status); 601 child_id_, route_id_, final_status);
585 CHECK(is_cancelled); 602 CHECK(is_cancelled);
586 603
587 // A different final status may have been set already from another thread. 604 // A different final status may have been set already from another thread.
588 // If so, use it instead. 605 // If so, use it instead.
589 if (!prerender_tracker_->GetFinalStatus(child_id_, route_id_, 606 if (!prerender_manager()->prerender_tracker()->
590 &final_status)) { 607 GetFinalStatus(child_id_, route_id_, &final_status)) {
591 NOTREACHED(); 608 NOTREACHED();
592 } 609 }
593 } 610 }
594 set_final_status(final_status); 611 SetFinalStatus(final_status);
595 612
596 prerendering_has_been_cancelled_ = true; 613 prerendering_has_been_cancelled_ = true;
597 prerender_manager_->AddToHistory(this); 614 prerender_manager_->AddToHistory(this);
598 prerender_manager_->MoveEntryToPendingDelete(this, final_status); 615 prerender_manager_->MoveEntryToPendingDelete(this, final_status);
599 616
600 // We may destroy the PrerenderContents before we have initialized the 617 // We may destroy the PrerenderContents before we have initialized the
601 // RenderViewHost. Otherwise set the Observer's PrerenderContents to NULL to 618 // RenderViewHost. Otherwise set the Observer's PrerenderContents to NULL to
602 // avoid any more messages being sent. 619 // avoid any more messages being sent.
603 if (render_view_host_observer_) 620 if (render_view_host_observer_)
604 render_view_host_observer_->set_prerender_contents(NULL); 621 render_view_host_observer_->set_prerender_contents(NULL);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
685 bool PrerenderContents::IsCrossSiteNavigationPending() const { 702 bool PrerenderContents::IsCrossSiteNavigationPending() const {
686 if (!prerender_contents_.get() || !prerender_contents_->web_contents()) 703 if (!prerender_contents_.get() || !prerender_contents_->web_contents())
687 return false; 704 return false;
688 const WebContents* web_contents = prerender_contents_->web_contents(); 705 const WebContents* web_contents = prerender_contents_->web_contents();
689 return (web_contents->GetSiteInstance() != 706 return (web_contents->GetSiteInstance() !=
690 web_contents->GetPendingSiteInstance()); 707 web_contents->GetPendingSiteInstance());
691 } 708 }
692 709
693 710
694 } // namespace prerender 711 } // namespace prerender
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698