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