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