1 // Copyright 2012 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.
5 #ifndef CHROME_BROWSER_SYNC_GLUE_SYNCED_SESSION_TRACKER_H_
6 #define CHROME_BROWSER_SYNC_GLUE_SYNCED_SESSION_TRACKER_H_
13 #include "base/basictypes.h"
14 #include "components/sessions/session_id.h"
15 #include "components/sessions/session_types.h"
16 #include "components/sync_driver/glue/synced_session.h"
17 #include "components/sync_driver/tab_node_pool.h"
19 namespace browser_sync
{
21 // Class to manage synced sessions. The tracker will own all SyncedSession
22 // and SyncedSessionTab objects it creates, and deletes them appropriately on
24 // Note: SyncedSession objects are created for all synced sessions, including
25 // the local session (whose tag we maintain separately).
26 class SyncedSessionTracker
{
28 SyncedSessionTracker();
29 ~SyncedSessionTracker();
31 // We track and distinguish the local session from foreign sessions.
32 void SetLocalSessionTag(const std::string
& local_session_tag
);
34 // Fill a preallocated vector with all foreign sessions we're tracking (skips
35 // the local session object). SyncedSession ownership remains within the
36 // SyncedSessionTracker.
37 // Returns true if we had foreign sessions to fill it with, false otherwise.
38 bool LookupAllForeignSessions(
39 std::vector
<const sync_driver::SyncedSession
*>* sessions
) const;
41 // Attempts to look up the session windows associatd with the session given
42 // by |session_tag|. Ownership Of SessionWindows stays within the
43 // SyncedSessionTracker.
44 // If lookup succeeds:
45 // - Fills windows with the SessionWindow pointers, returns true.
48 bool LookupSessionWindows(
49 const std::string
& session_tag
,
50 std::vector
<const sessions::SessionWindow
*>* windows
) const;
52 // Attempts to look up the tab associated with the given tag and tab id.
53 // Ownership of the SessionTab remains within the SyncedSessionTracker.
54 // If lookup succeeds:
55 // - Sets tab to point to the SessionTab, and returns true.
57 // - Returns false, tab is set to NULL.
58 bool LookupSessionTab(const std::string
& session_tag
,
59 SessionID::id_type tab_id
,
60 const sessions::SessionTab
** tab
) const;
62 // Allows retrieval of existing data for the local session. Unlike GetSession
63 // this won't create-if-not-present.
64 bool LookupLocalSession(const sync_driver::SyncedSession
** output
) const;
66 // Returns a pointer to the SyncedSession object associated with
67 // |session_tag|. If none exists, creates one. Ownership of the
68 // SyncedSession remains within the SyncedSessionTracker.
69 sync_driver::SyncedSession
* GetSession(const std::string
& session_tag
);
71 // Deletes the session associated with |session_tag| if it exists.
72 // Returns true if the session existed and was deleted, false otherwise.
73 bool DeleteSession(const std::string
& session_tag
);
75 // Resets the tracking information for the session specified by |session_tag|.
76 // This involves clearing all the windows and tabs from the session, while
77 // keeping pointers saved in the synced_window_map_ and synced_tab_map_.
78 // Once reset, all calls to PutWindowInSession and PutTabInWindow will denote
79 // that the requested windows and tabs are owned (by setting the boolean
80 // in their SessionWindowWrapper/SessionTabWrapper to true) and add them back
81 // to their session. The next call to CleanupSession(...) will delete those
82 // windows and tabs not owned.
83 void ResetSessionTracking(const std::string
& session_tag
);
85 // Deletes those windows and tabs associated with |session_tag| that are no
87 // See ResetSessionTracking(...).
88 void CleanupSession(const std::string
& session_tag
);
90 // Adds the window with id |window_id| to the session specified by
91 // |session_tag|, and markes the window as being owned. If none existed for
92 // that session, creates one. Similarly, if the session did not exist yet,
93 // creates it. Ownership of the SessionWindow remains within the
94 // SyncedSessionTracker.
95 void PutWindowInSession(const std::string
& session_tag
,
96 SessionID::id_type window_id
);
98 // Adds the tab with id |tab_id| to the window |window_id|, and marks it as
99 // being owned. If none existed for that session, creates one. Ownership of
100 // the SessionTab remains within the SyncedSessionTracker.
101 // Note: GetSession(..) must have already been called with |session_tag| to
102 // ensure we having mapping information for this session.
103 void PutTabInWindow(const std::string
& session_tag
,
104 SessionID::id_type window_id
,
105 SessionID::id_type tab_id
,
108 // Returns a pointer to the SessionTab object associated with |tab_id| for
109 // the session specified with |session_tag|. If none exists, creates one.
110 // Ownership of the SessionTab remains within the SyncedSessionTracker.
111 // |tab_node_id| must be a valid node id for the node backing this tab.
112 sessions::SessionTab
* GetTab(const std::string
& session_tag
,
113 SessionID::id_type tab_id
,
116 // Fills |tab_node_ids| with the tab node ids (see GetTab) for all the tabs*
117 // associated with the session having tag |session_tag|.
118 // Returns false if we don't have any record of the session. If no tabs were
119 // found as part of the session, the return value will be true but
120 // |tab_node_ids| will be empty.
122 // * - note that this only returns the ids we're aware of; it's possible we
123 // don't have the latest tab state from a foreign session and it's also
124 // possible we just haven't updated the tab_node_id for a tab yet, so the
125 // result list should not be treated as authoritative.
126 bool LookupTabNodeIds(const std::string
& session_tag
,
127 std::set
<int>* tab_node_ids
);
129 // Free the memory for all dynamically allocated objects and clear the
130 // tracking structures.
134 return synced_tab_map_
.empty() && synced_session_map_
.empty();
137 // Includes both foreign sessions and the local session.
138 size_t num_synced_sessions() const {
139 return synced_session_map_
.size();
142 // Returns the number of tabs associated with the specified session tag.
143 size_t num_synced_tabs(const std::string
& session_tag
) const {
144 SyncedTabMap::const_iterator iter
= synced_tab_map_
.find(session_tag
);
145 if (iter
!= synced_tab_map_
.end()) {
146 return iter
->second
.size();
152 // Datatypes for accessing session data. Neither of the *Wrappers actually
153 // have ownership of the Windows/Tabs, they just provide id-based access to
154 // them. The ownership remains within its containing session (for windows and
155 // mapped tabs, unmapped tabs are owned by the unmapped_tabs_ container).
156 // Note, we pair pointers with bools so that we can track what is owned and
157 // what can be deleted (see ResetSessionTracking(..) and CleanupSession(..)
159 // The wrappers also serve as a convenient place to augment state stored in
160 // SessionTab for sync purposes, such as |tab_node_id|.
161 // IsOwned is used as a wrapper constructor parameter for readability.
166 struct SessionTabWrapper
{
167 SessionTabWrapper() : tab_ptr(NULL
),
169 tab_node_id(TabNodePool::kInvalidTabNodeID
) {}
170 SessionTabWrapper(sessions::SessionTab
* tab_ptr
,
174 owned(owned
== IS_OWNED
),
175 tab_node_id(tab_node_id
) {}
176 sessions::SessionTab
* tab_ptr
;
178 // This is used as part of a mark-and-sweep approach to garbage
179 // collection for closed tabs that are no longer "in use", or "owned".
180 // ResetSessionTracking will clear |owned| bits, and if it is not claimed
181 // by a window by the time CleanupSession is called it will be deleted.
184 // This lets us identify the sync node that is "backing" this tab in the
185 // sync model, whether it is part of a local or foreign session. The
186 // "tab node id" is described in session_specifics.proto.
189 typedef std::map
<SessionID::id_type
, SessionTabWrapper
> IDToSessionTabMap
;
190 typedef std::map
<std::string
, IDToSessionTabMap
> SyncedTabMap
;
192 struct SessionWindowWrapper
{
193 SessionWindowWrapper() : window_ptr(NULL
), owned(false) {}
194 SessionWindowWrapper(sessions::SessionWindow
* window_ptr
, OwnedState owned
)
195 : window_ptr(window_ptr
),
196 owned(owned
== IS_OWNED
) {}
197 sessions::SessionWindow
* window_ptr
;
200 typedef std::map
<SessionID::id_type
, SessionWindowWrapper
>
201 IDToSessionWindowMap
;
202 typedef std::map
<std::string
, IDToSessionWindowMap
> SyncedWindowMap
;
204 typedef std::map
<std::string
, sync_driver::SyncedSession
*> SyncedSessionMap
;
206 // Helper methods for deleting SessionWindows and SessionTabs without owners.
207 bool DeleteOldSessionWindowIfNecessary(SessionWindowWrapper window_wrapper
);
208 bool DeleteOldSessionTabIfNecessary(SessionTabWrapper tab_wrapper
);
210 // Implementation for GetTab(...) above, permits invalid tab_node_id.
211 sessions::SessionTab
* GetTabImpl(const std::string
& session_tag
,
212 SessionID::id_type tab_id
,
215 // Per client mapping of tab id's to their SessionTab objects.
217 // Value: Tab id to SessionTabWrapper map.
218 SyncedTabMap synced_tab_map_
;
220 // Per client mapping of the window id's to their SessionWindow objects.
222 // Value: Window id to SessionWindowWrapper map.
223 SyncedWindowMap synced_window_map_
;
225 // Per client mapping synced session objects.
227 // Value: SyncedSession object pointer.
228 SyncedSessionMap synced_session_map_
;
230 // The set of tabs that we have seen, and created SessionTab objects for, but
231 // have not yet mapped to SyncedSessions. These are temporarily orphaned
232 // tabs, and won't be deleted if we delete synced_session_map_, but are still
233 // owned by the SyncedSessionTracker itself (and deleted on Clear()).
234 std::set
<sessions::SessionTab
*> unmapped_tabs_
;
236 // The tag for this machine's local session, so we can distinguish the foreign
238 std::string local_session_tag_
;
240 DISALLOW_COPY_AND_ASSIGN(SyncedSessionTracker
);
243 } // namespace browser_sync
245 #endif // CHROME_BROWSER_SYNC_GLUE_SYNCED_SESSION_TRACKER_H_