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