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