// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/instant/instant_loader_manager.h" #include "base/logging.h" #include "chrome/browser/instant/instant_loader.h" #include "chrome/browser/instant/instant_loader_delegate.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "content/browser/tab_contents/tab_contents.h" InstantLoaderManager::InstantLoaderManager( InstantLoaderDelegate* loader_delegate) : loader_delegate_(loader_delegate), current_loader_(NULL), pending_loader_(NULL) { } InstantLoaderManager::~InstantLoaderManager() { for (Loaders::iterator i = instant_loaders_.begin(); i != instant_loaders_.end(); ++i) { if (i->second == current_loader_) current_loader_ = NULL; if (i->second == pending_loader_) pending_loader_ = NULL; delete i->second; } instant_loaders_.clear(); delete current_loader_; delete pending_loader_; } InstantLoader* InstantLoaderManager::UpdateLoader( TemplateURLID instant_id, scoped_ptr<InstantLoader>* old_loader) { InstantLoader* old_current_loader = current_loader_; InstantLoader* old_pending_loader = pending_loader_; // Determine the new loader. InstantLoader* loader = NULL; if (instant_id) { loader = GetInstantLoader(instant_id); } else { if (current_loader_ && !current_loader_->template_url_id()) loader = current_loader_; else if (pending_loader_ && !pending_loader_->template_url_id()) loader = pending_loader_; else loader = CreateLoader(0); } if (loader->ready()) { // The loader is ready, make it the current loader no matter what. current_loader_ = loader; pending_loader_ = NULL; } else { // The loader isn't ready make it the current only if the current isn't // ready. If the current is ready, then stop the current and make the new // loader pending. if (!current_loader_ || !current_loader_->ready()) { current_loader_ = loader; DCHECK(!pending_loader_); } else { // preview_contents() may be null for tests. if (!current_loader_->template_url_id() && current_loader_->preview_contents()) { current_loader_->preview_contents()->tab_contents()->Stop(); } pending_loader_ = loader; } } if (current_loader_ != old_current_loader && old_current_loader && !old_current_loader->template_url_id()) { old_loader->reset(old_current_loader); } if (pending_loader_ != old_pending_loader && old_pending_loader && !old_pending_loader->template_url_id() && old_pending_loader != current_loader_) { DCHECK(!old_loader->get()); old_loader->reset(old_pending_loader); } return active_loader(); } bool InstantLoaderManager::WillUpateChangeActiveLoader( TemplateURLID instant_id) { return !active_loader() || active_loader()->template_url_id() != instant_id; } void InstantLoaderManager::MakePendingCurrent( scoped_ptr<InstantLoader>* old_loader) { DCHECK(current_loader_); DCHECK(pending_loader_); if (!current_loader_->template_url_id()) old_loader->reset(current_loader_); current_loader_ = pending_loader_; pending_loader_ = NULL; } InstantLoader* InstantLoaderManager::ReleaseCurrentLoader() { DCHECK(current_loader_); InstantLoader* loader = current_loader_; RemoveLoaderFromInstant(current_loader_); current_loader_ = NULL; return loader; } void InstantLoaderManager::DestroyLoader(InstantLoader* loader) { delete ReleaseLoader(loader); } InstantLoader* InstantLoaderManager::ReleaseLoader(InstantLoader* loader) { DCHECK(loader == current_loader_ || loader == pending_loader_ || (loader->template_url_id() && instant_loaders_.find(loader->template_url_id()) != instant_loaders_.end())); if (current_loader_ == loader) current_loader_ = pending_loader_; if (pending_loader_ == loader) pending_loader_ = NULL; RemoveLoaderFromInstant(loader); return loader; } void InstantLoaderManager::RemoveLoaderFromInstant(InstantLoader* loader) { if (!loader->template_url_id()) return; Loaders::iterator i = instant_loaders_.find(loader->template_url_id()); DCHECK(i != instant_loaders_.end()); instant_loaders_.erase(i); } InstantLoader* InstantLoaderManager::CreateLoader(TemplateURLID id) { InstantLoader* loader = new InstantLoader(loader_delegate_, id); if (id) instant_loaders_[id] = loader; return loader; } InstantLoader* InstantLoaderManager::GetInstantLoader(TemplateURLID id) { Loaders::iterator i = instant_loaders_.find(id); return i == instant_loaders_.end() ? CreateLoader(id) : i->second; }