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