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
ForeignSessionTracker()11 ForeignSessionTracker::ForeignSessionTracker() {
12 }
13
~ForeignSessionTracker()14 ForeignSessionTracker::~ForeignSessionTracker() {
15 clear();
16 }
17
LookupAllForeignSessions(std::vector<const ForeignSession * > * sessions)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
LookupSessionWindows(const std::string & foreign_session_tag,std::vector<SessionWindow * > * windows)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
LookupSessionTab(const std::string & tag,SessionID::id_type tab_id,const SessionTab ** tab)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
GetForeignSession(const std::string & foreign_session_tag)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
DeleteForeignSession(const std::string & foreign_session_tag)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
GetSessionTab(const std::string & foreign_session_tag,SessionID::id_type tab_id,bool has_window)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
clear()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