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/sync/glue/foreign_session_tracker.h" 6#include "chrome/browser/sync/glue/session_model_associator.h" 7 8namespace browser_sync { 9 10 11ForeignSessionTracker::ForeignSessionTracker() { 12} 13 14ForeignSessionTracker::~ForeignSessionTracker() { 15 clear(); 16} 17 18bool ForeignSessionTracker::LookupAllForeignSessions( 19 std::vector<const ForeignSession*>* sessions) { 20 DCHECK(sessions); 21 // Fill vector of sessions from our foreign session map. 22 for (ForeignSessionMap::const_iterator i = 23 foreign_session_map_.begin(); i != foreign_session_map_.end(); ++i) { 24 // Only include sessions with open tabs. 25 ForeignSession* foreign_session = i->second; 26 if (!foreign_session->windows.empty() && 27 !SessionModelAssociator::SessionWindowHasNoTabsToSync( 28 *foreign_session->windows[0])) { 29 sessions->push_back(foreign_session); 30 } 31 } 32 33 return !sessions->empty(); 34} 35 36bool ForeignSessionTracker::LookupSessionWindows( 37 const std::string& foreign_session_tag, 38 std::vector<SessionWindow*>* windows) { 39 DCHECK(windows); 40 ForeignSessionMap::iterator iter = foreign_session_map_.find( 41 foreign_session_tag); 42 if (iter == foreign_session_map_.end()) 43 return false; 44 *windows = iter->second->windows; 45 return true; 46} 47 48bool ForeignSessionTracker::LookupSessionTab( 49 const std::string& tag, 50 SessionID::id_type tab_id, 51 const SessionTab** tab) { 52 DCHECK(tab); 53 if (foreign_tab_map_.find(tag) == foreign_tab_map_.end()) { 54 // We have no record of this session. 55 *tab = NULL; 56 return false; 57 } 58 if (foreign_tab_map_[tag]->find(tab_id) == foreign_tab_map_[tag]->end()) { 59 // We have no record of this tab. 60 *tab = NULL; 61 return false; 62 } 63 *tab = (*foreign_tab_map_[tag])[tab_id]; 64 return true; 65} 66 67ForeignSession* ForeignSessionTracker::GetForeignSession( 68 const std::string& foreign_session_tag) { 69 scoped_ptr<ForeignSession> foreign_session; 70 if (foreign_session_map_.find(foreign_session_tag) != 71 foreign_session_map_.end()) { 72 foreign_session.reset(foreign_session_map_[foreign_session_tag]); 73 } else { 74 foreign_session.reset(new ForeignSession); 75 foreign_session->foreign_session_tag = foreign_session_tag; 76 foreign_session_map_[foreign_session_tag] = foreign_session.get(); 77 } 78 DCHECK(foreign_session.get()); 79 return foreign_session.release(); 80} 81 82bool ForeignSessionTracker::DeleteForeignSession( 83 const std::string& foreign_session_tag) { 84 ForeignSessionMap::iterator iter = 85 foreign_session_map_.find(foreign_session_tag); 86 if (iter != foreign_session_map_.end()) { 87 delete iter->second; // Delete the ForeignSession object. 88 foreign_session_map_.erase(iter); 89 return true; 90 } else { 91 return false; 92 } 93} 94 95SessionTab* ForeignSessionTracker::GetSessionTab( 96 const std::string& foreign_session_tag, 97 SessionID::id_type tab_id, 98 bool has_window) { 99 if (foreign_tab_map_.find(foreign_session_tag) == foreign_tab_map_.end()) 100 foreign_tab_map_[foreign_session_tag] = new IDToSessionTabMap; 101 scoped_ptr<SessionTab> tab; 102 IDToSessionTabMap::iterator iter = 103 foreign_tab_map_[foreign_session_tag]->find(tab_id); 104 if (iter != foreign_tab_map_[foreign_session_tag]->end()) { 105 tab.reset(iter->second); 106 if (has_window) // This tab is linked to a window, so it's not an orphan. 107 unmapped_tabs_.erase(tab.get()); 108 VLOG(1) << "Associating " << foreign_session_tag << "'s seen tab " << 109 tab_id << " at " << tab.get(); 110 } else { 111 tab.reset(new SessionTab()); 112 (*foreign_tab_map_[foreign_session_tag])[tab_id] = tab.get(); 113 if (!has_window) // This tab is not linked to a window, it's an orphan. 114 unmapped_tabs_.insert(tab.get()); 115 VLOG(1) << "Associating " << foreign_session_tag << "'s new tab " << 116 tab_id << " at " << tab.get(); 117 } 118 DCHECK(tab.get()); 119 return tab.release(); 120} 121 122void ForeignSessionTracker::clear() { 123 // Delete ForeignSession objects (which also deletes all their windows/tabs). 124 STLDeleteContainerPairSecondPointers(foreign_session_map_.begin(), 125 foreign_session_map_.end()); 126 foreign_session_map_.clear(); 127 128 // Delete IDToSessTab maps. Does not delete the SessionTab objects, because 129 // they should already be referenced through foreign_session_map_. 130 STLDeleteContainerPairSecondPointers(foreign_tab_map_.begin(), 131 foreign_tab_map_.end()); 132 foreign_tab_map_.clear(); 133 134 // Go through and delete any tabs we had allocated but had not yet placed into 135 // a ForeignSessionobject. 136 STLDeleteContainerPointers(unmapped_tabs_.begin(), unmapped_tabs_.end()); 137 unmapped_tabs_.clear(); 138} 139 140} // namespace browser_sync 141