prerender_handle.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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
12namespace prerender {
13
14PrerenderHandle::Observer::Observer() {
15}
16
17PrerenderHandle::Observer::~Observer() {
18}
19
20PrerenderHandle::~PrerenderHandle() {
21  if (prerender_data_) {
22    prerender_data_->contents()->RemoveObserver(this);
23  }
24}
25
26void PrerenderHandle::SetObserver(Observer* observer) {
27  DCHECK_NE(static_cast<Observer*>(NULL), observer);
28  observer_ = observer;
29}
30
31void PrerenderHandle::OnNavigateAway() {
32  DCHECK(CalledOnValidThread());
33  if (prerender_data_)
34    prerender_data_->OnHandleNavigatedAway(this);
35}
36
37void PrerenderHandle::OnCancel() {
38  DCHECK(CalledOnValidThread());
39  if (prerender_data_)
40    prerender_data_->OnHandleCanceled(this);
41}
42
43bool PrerenderHandle::IsPrerendering() const {
44  DCHECK(CalledOnValidThread());
45  return prerender_data_ != NULL;
46}
47
48bool PrerenderHandle::IsFinishedLoading() const {
49  DCHECK(CalledOnValidThread());
50  if (!prerender_data_)
51    return false;
52  return prerender_data_->contents()->has_finished_loading();
53}
54
55PrerenderHandle::PrerenderHandle(
56    PrerenderManager::PrerenderData* prerender_data)
57    : observer_(NULL),
58      weak_ptr_factory_(this) {
59  if (prerender_data) {
60    prerender_data_ = prerender_data->AsWeakPtr();
61    prerender_data->OnHandleCreated(this);
62  }
63}
64
65void PrerenderHandle::AdoptPrerenderDataFrom(PrerenderHandle* other_handle) {
66  DCHECK_EQ(static_cast<PrerenderManager::PrerenderData*>(NULL),
67            prerender_data_);
68  if (other_handle->prerender_data_ &&
69      other_handle->prerender_data_->contents()) {
70    other_handle->prerender_data_->contents()->RemoveObserver(other_handle);
71  }
72
73  prerender_data_ = other_handle->prerender_data_;
74  other_handle->prerender_data_.reset();
75
76  if (prerender_data_) {
77    DCHECK_NE(static_cast<PrerenderContents*>(NULL),
78              prerender_data_->contents());
79    prerender_data_->contents()->AddObserver(this);
80    // We are joining a prerender that has already started so we fire off an
81    // extra start event at ourselves.
82    OnPrerenderStart(prerender_data_->contents());
83  }
84}
85
86void PrerenderHandle::OnPrerenderStart(PrerenderContents* prerender_contents) {
87  DCHECK(CalledOnValidThread());
88  DCHECK(prerender_data_);
89  DCHECK_EQ(prerender_data_->contents(), prerender_contents);
90  if (observer_)
91    observer_->OnPrerenderStart(this);
92}
93
94void PrerenderHandle::OnPrerenderStopLoading(
95    PrerenderContents* prerender_contents) {
96  DCHECK(CalledOnValidThread());
97  DCHECK(prerender_data_);
98  DCHECK_EQ(prerender_data_->contents(), prerender_contents);
99  if (observer_)
100    observer_->OnPrerenderStopLoading(this);
101}
102
103void PrerenderHandle::OnPrerenderStop(PrerenderContents* prerender_contents) {
104  DCHECK(CalledOnValidThread());
105  if (observer_)
106    observer_->OnPrerenderStop(this);
107}
108
109void PrerenderHandle::OnPrerenderAddAlias(PrerenderContents* prerender_contents,
110                                          const GURL& alias_url) {
111  DCHECK(CalledOnValidThread());
112  DCHECK(prerender_data_);
113  DCHECK_EQ(prerender_data_->contents(), prerender_contents);
114  if (observer_)
115    observer_->OnPrerenderAddAlias(this, alias_url);
116}
117
118void 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}  // namespace prerender
133