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 8 namespace browser_sync { 9 10 11 ForeignSessionTracker::ForeignSessionTracker() { 12 } 13 14 ForeignSessionTracker::~ForeignSessionTracker() { 15 clear(); 16 } 17 18 bool 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 36 bool 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 48 bool 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 67 ForeignSession* 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 82 bool 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 95 SessionTab* 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 122 void 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