Home | History | Annotate | Download | only in instant
      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 
     13 InstantLoaderManager::InstantLoaderManager(
     14     InstantLoaderDelegate* loader_delegate)
     15     : loader_delegate_(loader_delegate),
     16       current_loader_(NULL),
     17       pending_loader_(NULL) {
     18 }
     19 
     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 
     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 
     89 bool InstantLoaderManager::WillUpateChangeActiveLoader(
     90     TemplateURLID instant_id) {
     91   return !active_loader() || active_loader()->template_url_id() != instant_id;
     92 }
     93 
     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 
    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 
    114 void InstantLoaderManager::DestroyLoader(InstantLoader* loader) {
    115   delete ReleaseLoader(loader);
    116 }
    117 
    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 
    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 
    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 
    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