• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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/instant/instant_loader_manager.h"
6 
7 #include "base/logging.h"
8 #include "chrome/browser/instant/instant_loader.h"
9 #include "chrome/browser/instant/instant_loader_delegate.h"
10 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
11 #include "content/browser/tab_contents/tab_contents.h"
12 
InstantLoaderManager(InstantLoaderDelegate * loader_delegate)13 InstantLoaderManager::InstantLoaderManager(
14     InstantLoaderDelegate* loader_delegate)
15     : loader_delegate_(loader_delegate),
16       current_loader_(NULL),
17       pending_loader_(NULL) {
18 }
19 
~InstantLoaderManager()20 InstantLoaderManager::~InstantLoaderManager() {
21   for (Loaders::iterator i = instant_loaders_.begin();
22        i != instant_loaders_.end(); ++i) {
23     if (i->second == current_loader_)
24       current_loader_ = NULL;
25     if (i->second == pending_loader_)
26       pending_loader_ = NULL;
27     delete i->second;
28   }
29   instant_loaders_.clear();
30 
31   delete current_loader_;
32   delete pending_loader_;
33 }
34 
UpdateLoader(TemplateURLID instant_id,scoped_ptr<InstantLoader> * old_loader)35 InstantLoader* InstantLoaderManager::UpdateLoader(
36     TemplateURLID instant_id,
37     scoped_ptr<InstantLoader>* old_loader) {
38   InstantLoader* old_current_loader = current_loader_;
39   InstantLoader* old_pending_loader = pending_loader_;
40 
41   // Determine the new loader.
42   InstantLoader* loader = NULL;
43   if (instant_id) {
44     loader = GetInstantLoader(instant_id);
45   } else {
46     if (current_loader_ && !current_loader_->template_url_id())
47       loader = current_loader_;
48     else if (pending_loader_ && !pending_loader_->template_url_id())
49       loader = pending_loader_;
50     else
51       loader = CreateLoader(0);
52   }
53 
54   if (loader->ready()) {
55     // The loader is ready, make it the current loader no matter what.
56     current_loader_ = loader;
57     pending_loader_ = NULL;
58   } else {
59     // The loader isn't ready make it the current only if the current isn't
60     // ready. If the current is ready, then stop the current and make the new
61     // loader pending.
62     if (!current_loader_ || !current_loader_->ready()) {
63       current_loader_ = loader;
64       DCHECK(!pending_loader_);
65     } else {
66       // preview_contents() may be null for tests.
67       if (!current_loader_->template_url_id() &&
68           current_loader_->preview_contents()) {
69         current_loader_->preview_contents()->tab_contents()->Stop();
70       }
71       pending_loader_ = loader;
72     }
73   }
74 
75   if (current_loader_ != old_current_loader && old_current_loader &&
76       !old_current_loader->template_url_id()) {
77     old_loader->reset(old_current_loader);
78   }
79   if (pending_loader_ != old_pending_loader && old_pending_loader &&
80       !old_pending_loader->template_url_id() &&
81       old_pending_loader != current_loader_) {
82     DCHECK(!old_loader->get());
83     old_loader->reset(old_pending_loader);
84   }
85 
86   return active_loader();
87 }
88 
WillUpateChangeActiveLoader(TemplateURLID instant_id)89 bool InstantLoaderManager::WillUpateChangeActiveLoader(
90     TemplateURLID instant_id) {
91   return !active_loader() || active_loader()->template_url_id() != instant_id;
92 }
93 
MakePendingCurrent(scoped_ptr<InstantLoader> * old_loader)94 void InstantLoaderManager::MakePendingCurrent(
95     scoped_ptr<InstantLoader>* old_loader) {
96   DCHECK(current_loader_);
97   DCHECK(pending_loader_);
98 
99   if (!current_loader_->template_url_id())
100     old_loader->reset(current_loader_);
101 
102   current_loader_ = pending_loader_;
103   pending_loader_ = NULL;
104 }
105 
ReleaseCurrentLoader()106 InstantLoader* InstantLoaderManager::ReleaseCurrentLoader() {
107   DCHECK(current_loader_);
108   InstantLoader* loader = current_loader_;
109   RemoveLoaderFromInstant(current_loader_);
110   current_loader_ = NULL;
111   return loader;
112 }
113 
DestroyLoader(InstantLoader * loader)114 void InstantLoaderManager::DestroyLoader(InstantLoader* loader) {
115   delete ReleaseLoader(loader);
116 }
117 
ReleaseLoader(InstantLoader * loader)118 InstantLoader* InstantLoaderManager::ReleaseLoader(InstantLoader* loader) {
119   DCHECK(loader == current_loader_ || loader == pending_loader_ ||
120          (loader->template_url_id() &&
121           instant_loaders_.find(loader->template_url_id()) !=
122           instant_loaders_.end()));
123 
124   if (current_loader_ == loader)
125     current_loader_ = pending_loader_;
126 
127   if (pending_loader_ == loader)
128     pending_loader_ = NULL;
129 
130   RemoveLoaderFromInstant(loader);
131 
132   return loader;
133 }
134 
RemoveLoaderFromInstant(InstantLoader * loader)135 void InstantLoaderManager::RemoveLoaderFromInstant(InstantLoader* loader) {
136   if (!loader->template_url_id())
137     return;
138 
139   Loaders::iterator i = instant_loaders_.find(loader->template_url_id());
140   DCHECK(i != instant_loaders_.end());
141   instant_loaders_.erase(i);
142 }
143 
CreateLoader(TemplateURLID id)144 InstantLoader* InstantLoaderManager::CreateLoader(TemplateURLID id) {
145   InstantLoader* loader = new InstantLoader(loader_delegate_, id);
146   if (id)
147     instant_loaders_[id] = loader;
148   return loader;
149 }
150 
GetInstantLoader(TemplateURLID id)151 InstantLoader* InstantLoaderManager::GetInstantLoader(TemplateURLID id) {
152   Loaders::iterator i = instant_loaders_.find(id);
153   return i == instant_loaders_.end() ? CreateLoader(id) : i->second;
154 }
155