Home | History | Annotate | Download | only in prerender
      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
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/prerender/prerender_handle.h"
      6 
      7 #include <algorithm>
      8 
      9 #include "base/logging.h"
     10 #include "chrome/browser/prerender/prerender_contents.h"
     11 
     12 namespace prerender {
     13 
     14 PrerenderHandle::Observer::Observer() {
     15 }
     16 
     17 PrerenderHandle::Observer::~Observer() {
     18 }
     19 
     20 PrerenderHandle::~PrerenderHandle() {
     21   if (prerender_data_.get()) {
     22     prerender_data_->contents()->RemoveObserver(this);
     23   }
     24 }
     25 
     26 void PrerenderHandle::SetObserver(Observer* observer) {
     27   DCHECK_NE(static_cast<Observer*>(NULL), observer);
     28   observer_ = observer;
     29 }
     30 
     31 void PrerenderHandle::OnNavigateAway() {
     32   DCHECK(CalledOnValidThread());
     33   if (prerender_data_.get())
     34     prerender_data_->OnHandleNavigatedAway(this);
     35 }
     36 
     37 void PrerenderHandle::OnCancel() {
     38   DCHECK(CalledOnValidThread());
     39   if (prerender_data_.get())
     40     prerender_data_->OnHandleCanceled(this);
     41 }
     42 
     43 bool PrerenderHandle::IsPrerendering() const {
     44   DCHECK(CalledOnValidThread());
     45   return prerender_data_.get() != NULL;
     46 }
     47 
     48 bool PrerenderHandle::IsFinishedLoading() const {
     49   DCHECK(CalledOnValidThread());
     50   if (!prerender_data_.get())
     51     return false;
     52   return prerender_data_->contents()->has_finished_loading();
     53 }
     54 
     55 bool PrerenderHandle::Matches(
     56     const GURL& url,
     57     const content::SessionStorageNamespace* session_storage_namespace) const {
     58   DCHECK(CalledOnValidThread());
     59   if (!prerender_data_.get())
     60     return false;
     61   return prerender_data_->contents()->Matches(url, session_storage_namespace);
     62 }
     63 
     64 PrerenderHandle::PrerenderHandle(
     65     PrerenderManager::PrerenderData* prerender_data)
     66     : observer_(NULL),
     67       weak_ptr_factory_(this) {
     68   if (prerender_data) {
     69     prerender_data_ = prerender_data->AsWeakPtr();
     70     prerender_data->OnHandleCreated(this);
     71   }
     72 }
     73 
     74 void PrerenderHandle::AdoptPrerenderDataFrom(PrerenderHandle* other_handle) {
     75   DCHECK_EQ(static_cast<PrerenderManager::PrerenderData*>(NULL),
     76             prerender_data_.get());
     77   if (other_handle->prerender_data_.get() &&
     78       other_handle->prerender_data_->contents()) {
     79     other_handle->prerender_data_->contents()->RemoveObserver(other_handle);
     80   }
     81 
     82   prerender_data_ = other_handle->prerender_data_;
     83   other_handle->prerender_data_.reset();
     84 
     85   if (prerender_data_.get()) {
     86     DCHECK_NE(static_cast<PrerenderContents*>(NULL),
     87               prerender_data_->contents());
     88     prerender_data_->contents()->AddObserver(this);
     89     // We are joining a prerender that has already started so we fire off an
     90     // extra start event at ourselves.
     91     OnPrerenderStart(prerender_data_->contents());
     92   }
     93 }
     94 
     95 void PrerenderHandle::OnPrerenderStart(PrerenderContents* prerender_contents) {
     96   DCHECK(CalledOnValidThread());
     97   DCHECK(prerender_data_.get());
     98   DCHECK_EQ(prerender_data_->contents(), prerender_contents);
     99   if (observer_)
    100     observer_->OnPrerenderStart(this);
    101 }
    102 
    103 void PrerenderHandle::OnPrerenderStopLoading(
    104     PrerenderContents* prerender_contents) {
    105   DCHECK(CalledOnValidThread());
    106   DCHECK(prerender_data_.get());
    107   DCHECK_EQ(prerender_data_->contents(), prerender_contents);
    108   if (observer_)
    109     observer_->OnPrerenderStopLoading(this);
    110 }
    111 
    112 void PrerenderHandle::OnPrerenderStop(PrerenderContents* prerender_contents) {
    113   DCHECK(CalledOnValidThread());
    114   if (observer_)
    115     observer_->OnPrerenderStop(this);
    116 }
    117 
    118 void PrerenderHandle::OnPrerenderCreatedMatchCompleteReplacement(
    119     PrerenderContents* contents, PrerenderContents* replacement) {
    120   DCHECK(CalledOnValidThread());
    121 
    122   // This should occur in the middle of the surgery on the PrerenderData, and
    123   // so we expect to not have our new contents in our PrerenderData yet. The
    124   // switch occurs in
    125   // PrerenderManager::PrerenderData::MakeIntoMatchCompleteReplacement, so
    126   // this method only needs to switch observing.
    127 
    128   contents->RemoveObserver(this);
    129   replacement->AddObserver(this);
    130 }
    131 
    132 bool PrerenderHandle::RepresentingSamePrerenderAs(
    133     PrerenderHandle* other) const {
    134   return other && other->prerender_data_.get() && prerender_data_.get()
    135       && prerender_data_.get() == other->prerender_data_.get();
    136 }
    137 
    138 }  // namespace prerender
    139