普通文本  |  141行  |  4.71 KB

// Copyright (c) 2010 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/sync/glue/foreign_session_tracker.h"
#include "chrome/browser/sync/glue/session_model_associator.h"

namespace browser_sync {


ForeignSessionTracker::ForeignSessionTracker() {
}

ForeignSessionTracker::~ForeignSessionTracker() {
  clear();
}

bool ForeignSessionTracker::LookupAllForeignSessions(
    std::vector<const ForeignSession*>* sessions) {
  DCHECK(sessions);
  // Fill vector of sessions from our foreign session map.
  for (ForeignSessionMap::const_iterator i =
    foreign_session_map_.begin(); i != foreign_session_map_.end(); ++i) {
    // Only include sessions with open tabs.
    ForeignSession* foreign_session = i->second;
    if (!foreign_session->windows.empty() &&
        !SessionModelAssociator::SessionWindowHasNoTabsToSync(
            *foreign_session->windows[0])) {
      sessions->push_back(foreign_session);
    }
  }

  return !sessions->empty();
}

bool ForeignSessionTracker::LookupSessionWindows(
    const std::string& foreign_session_tag,
    std::vector<SessionWindow*>* windows) {
  DCHECK(windows);
  ForeignSessionMap::iterator iter = foreign_session_map_.find(
      foreign_session_tag);
  if (iter == foreign_session_map_.end())
    return false;
  *windows = iter->second->windows;
  return true;
}

bool ForeignSessionTracker::LookupSessionTab(
    const std::string& tag,
    SessionID::id_type tab_id,
    const SessionTab** tab) {
  DCHECK(tab);
  if (foreign_tab_map_.find(tag) == foreign_tab_map_.end()) {
    // We have no record of this session.
    *tab = NULL;
    return false;
  }
  if (foreign_tab_map_[tag]->find(tab_id) == foreign_tab_map_[tag]->end()) {
    // We have no record of this tab.
    *tab = NULL;
    return false;
  }
  *tab = (*foreign_tab_map_[tag])[tab_id];
  return true;
}

ForeignSession* ForeignSessionTracker::GetForeignSession(
    const std::string& foreign_session_tag) {
  scoped_ptr<ForeignSession> foreign_session;
  if (foreign_session_map_.find(foreign_session_tag) !=
      foreign_session_map_.end()) {
    foreign_session.reset(foreign_session_map_[foreign_session_tag]);
  } else {
    foreign_session.reset(new ForeignSession);
    foreign_session->foreign_session_tag = foreign_session_tag;
    foreign_session_map_[foreign_session_tag] = foreign_session.get();
  }
  DCHECK(foreign_session.get());
  return foreign_session.release();
}

bool ForeignSessionTracker::DeleteForeignSession(
    const std::string& foreign_session_tag) {
    ForeignSessionMap::iterator iter =
        foreign_session_map_.find(foreign_session_tag);
  if (iter != foreign_session_map_.end()) {
    delete iter->second;  // Delete the ForeignSession object.
    foreign_session_map_.erase(iter);
    return true;
  } else {
    return false;
  }
}

SessionTab* ForeignSessionTracker::GetSessionTab(
    const std::string& foreign_session_tag,
    SessionID::id_type tab_id,
    bool has_window) {
  if (foreign_tab_map_.find(foreign_session_tag) == foreign_tab_map_.end())
    foreign_tab_map_[foreign_session_tag] = new IDToSessionTabMap;
  scoped_ptr<SessionTab> tab;
  IDToSessionTabMap::iterator iter =
      foreign_tab_map_[foreign_session_tag]->find(tab_id);
  if (iter != foreign_tab_map_[foreign_session_tag]->end()) {
    tab.reset(iter->second);
    if (has_window)  // This tab is linked to a window, so it's not an orphan.
      unmapped_tabs_.erase(tab.get());
    VLOG(1) << "Associating " << foreign_session_tag << "'s seen tab " <<
        tab_id  << " at " << tab.get();
  } else {
    tab.reset(new SessionTab());
    (*foreign_tab_map_[foreign_session_tag])[tab_id] = tab.get();
    if (!has_window)  // This tab is not linked to a window, it's an orphan.
    unmapped_tabs_.insert(tab.get());
    VLOG(1) << "Associating " << foreign_session_tag << "'s new tab " <<
        tab_id  << " at " << tab.get();
  }
  DCHECK(tab.get());
  return tab.release();
}

void ForeignSessionTracker::clear() {
  // Delete ForeignSession objects (which also deletes all their windows/tabs).
  STLDeleteContainerPairSecondPointers(foreign_session_map_.begin(),
      foreign_session_map_.end());
  foreign_session_map_.clear();

  // Delete IDToSessTab maps. Does not delete the SessionTab objects, because
  // they should already be referenced through foreign_session_map_.
  STLDeleteContainerPairSecondPointers(foreign_tab_map_.begin(),
      foreign_tab_map_.end());
  foreign_tab_map_.clear();

  // Go through and delete any tabs we had allocated but had not yet placed into
  // a ForeignSessionobject.
  STLDeleteContainerPointers(unmapped_tabs_.begin(), unmapped_tabs_.end());
  unmapped_tabs_.clear();
}

}  // namespace browser_sync