1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Use of this source code is governed by a BSD-style license that can be
3bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// found in the LICENSE file.
4bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
5bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#ifndef CHROME_BROWSER_SYNC_GLUE_SESSION_MODEL_ASSOCIATOR_H_
6bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#define CHROME_BROWSER_SYNC_GLUE_SESSION_MODEL_ASSOCIATOR_H_
7bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#pragma once
8bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
93f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include <map>
10bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include <string>
11bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include <vector>
12bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
13bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/basictypes.h"
14dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/format_macros.h"
15bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/gtest_prod_util.h"
16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_vector.h"
17bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/observer_list.h"
183f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/string_util.h"
193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/non_thread_safe.h"
203f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/utf_string_conversions.h"
213f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "chrome/browser/sessions/session_id.h"
22bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/sessions/session_service.h"
23bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/sessions/session_types.h"
24bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/sync/engine/syncapi.h"
253f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "chrome/browser/sync/glue/foreign_session_tracker.h"
26bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/sync/glue/model_associator.h"
27bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/sync/protocol/session_specifics.pb.h"
28bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/sync/syncable/model_type.h"
29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_window.h"
30dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h"
31bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
32bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenclass Profile;
33bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenclass ProfileSyncService;
34bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
35bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsennamespace sync_api {
36bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenclass ReadNode;
37bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenclass WriteNode;
38bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenclass WriteTransaction;
39bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}  // namespace sync_api
40bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
41bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsennamespace sync_pb {
42bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenclass SessionSpecifics;
43bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}  // namespace sync_pb
44bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
45bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsennamespace browser_sync {
46bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
47bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenstatic const char kSessionsTag[] = "google_chrome_sessions";
48731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
49bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Contains all logic for associating the Chrome sessions model and
50bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// the sync sessions model.
513f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenclass SessionModelAssociator
523f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    : public PerDataTypeAssociatorInterface<TabContents, size_t>,
533f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      public base::NonThreadSafe {
54bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen public:
55bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Does not take ownership of sync_service.
56bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  explicit SessionModelAssociator(ProfileSyncService* sync_service);
57dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  SessionModelAssociator(ProfileSyncService* sync_service,
58dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                         bool setup_for_test);
59bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  virtual ~SessionModelAssociator();
60bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
613f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // The has_nodes out parameter is set to true if the sync model has
623f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // nodes other than the permanent tagged nodes.  The method may
633f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // return false if an error occurred.
643f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  virtual bool SyncModelHasUserCreatedNodes(bool* has_nodes);
653f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
66bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // AssociatorInterface and PerDataTypeAssociator Interface implementation.
67bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  virtual void AbortAssociation() {
683f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // No implementation needed, this associator runs on the main thread.
69731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
70bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // See ModelAssociator interface.
72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual bool CryptoReadyIfNecessary();
73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
743f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Returns sync id for the given chrome model id.
753f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Returns sync_api::kInvalidId if the sync node is not found for the given
763f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // chrome id.
773f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  virtual int64 GetSyncIdFromChromeId(const size_t& id);
78bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
793f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Returns sync id for the given session tag.
803f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Returns sync_api::kInvalidId if the sync node is not found for the given
813f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // tag
823f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  virtual int64 GetSyncIdFromSessionTag(const std::string& tag);
83bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
843f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Not used.
8572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual const TabContents* GetChromeNodeFromSyncId(int64 sync_id);
86bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
873f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Not used.
8872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual bool InitSyncNodeFromChromeId(const size_t& id,
8972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                        sync_api::BaseNode* sync_node);
90bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
913f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Resync local window information. Updates the local sessions header node
923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // with the status of open windows and the order of tabs they contain. Should
933f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // only be called for changes that affect a window, not a change within a
943f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // single tab.
953f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  //
963f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // If |reload_tabs| is true, will also resync all tabs (same as calling
973f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // ReassociateTabs with a vector of all tabs).
983f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  void ReassociateWindows(bool reload_tabs);
993f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1003f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Loads and reassociates the local tabs referenced in |tabs|.
1013f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  void ReassociateTabs(const std::vector<TabContents*>& tabs);
1023f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1033f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Reassociates a single tab with the sync model. Will check if the tab
1043f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // already is associated with a sync node and allocate one if necessary.
1053f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  void ReassociateTab(const TabContents& tab);
1063f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1073f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Associate a local tab and it's sync node. Will overwrite the contents of
1083f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // the sync node with new specifics built from the tab.
1093f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  virtual void Associate(const TabContents* tab, int64 sync_id);
1103f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1113f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Looks up the specified sync node, and marks that tab as closed, then marks
1123f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // the node as free and deletes association.
1133f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  virtual void Disassociate(int64 sync_id);
1143f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1153f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Load any foreign session info stored in sync db and update the sync db
1163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // with local client data. Processes/reuses any sync nodes owned by this
1173f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // client and creates any further sync nodes needed to store local header and
1183f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // tab info.
1193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  virtual bool AssociateModels();
120bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
121bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Initializes the given sync node from the given chrome node id.
122bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Returns false if no sync node was found for the given chrome node id or
123bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // if the initialization of sync node fails.
12421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  virtual bool InitSyncNodeFromChromeId(const std::string& id,
12521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                        sync_api::BaseNode* sync_node);
126bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
1273f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Clear local sync data buffers. Does not delete sync nodes to avoid
1283f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // tombstones. TODO(zea): way to eventually delete orphaned nodes.
1293f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  virtual bool DisassociateModels();
130bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
131bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Returns the tag used to uniquely identify this machine's session in the
132bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // sync model.
1333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  inline const std::string& GetCurrentMachineTag() {
1343f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    DCHECK(!current_machine_tag_.empty());
1353f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    return current_machine_tag_;
1363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  }
137bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
1383f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Load and associate window and tab data for a foreign session
1393f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  bool AssociateForeignSpecifics(const sync_pb::SessionSpecifics& specifics,
1403f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                 int64 modification_time);
141731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1423f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Removes a foreign session from our internal bookkeeping.
1433f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  void DisassociateForeignSession(const std::string& foreign_session_tag);
1443f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1453f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Builds a list of all foreign sessions.
1463f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Caller does NOT own ForeignSession objects.
1473f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  bool GetAllForeignSessions(std::vector<const ForeignSession*>* sessions);
148bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
1493f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Loads all windows for foreign session with session tag |tag|.
1503f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Caller does NOT own ForeignSession objects.
1513f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  bool GetForeignSession(const std::string& tag,
1523f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                         std::vector<SessionWindow*>* windows);
153731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1543f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Looks up the foreign tab identified by |tab_id| and belonging to foreign
1553f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // session |tag|.
1563f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Caller does NOT own the SessionTab object.
1573f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  bool GetForeignTab(const std::string& tag,
1583f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                     const SessionID::id_type tab_id,
1593f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                     const SessionTab** tab);
160bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
1613f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Specifies whether the window has tabs to sync. The new tab page does not
1623f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // count. If no tabs to sync, it returns true, otherwise false;
1633f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  static bool SessionWindowHasNoTabsToSync(const SessionWindow& window);
164513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
1653f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Control which local tabs we're interested in syncing.
1663f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Ensures the profile matches sync's profile and that the tab has at least
1673f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // one navigation entry and is not an empty tab.
1683f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  bool IsValidTab(const TabContents& tab);
169bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
1703f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Control which foreign tabs we're interested in displaying.
1713f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Checks that the tab has navigations and is not a new tab.
1723f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Note: a new tab page with back/forward history is valid.
1733f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  static bool IsValidSessionTab(const SessionTab& tab);
174bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
175bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Returns the syncable model type.
176bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  static syncable::ModelType model_type() { return syncable::SESSIONS; }
177bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
178bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen private:
179bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  FRIEND_TEST_ALL_PREFIXES(ProfileSyncServiceSessionTest, WriteSessionToNode);
180bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  FRIEND_TEST_ALL_PREFIXES(ProfileSyncServiceSessionTest,
1813f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                           WriteFilledSessionToNode);
1823f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  FRIEND_TEST_ALL_PREFIXES(ProfileSyncServiceSessionTest,
183bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                           WriteForeignSessionToNode);
1843f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  FRIEND_TEST_ALL_PREFIXES(ProfileSyncServiceSessionTest, TabNodePoolEmpty);
1853f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  FRIEND_TEST_ALL_PREFIXES(ProfileSyncServiceSessionTest, TabNodePoolNonEmpty);
1863f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  FRIEND_TEST_ALL_PREFIXES(SessionModelAssociatorTest, PopulateSessionWindow);
1873f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  FRIEND_TEST_ALL_PREFIXES(SessionModelAssociatorTest, PopulateSessionTab);
1883f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1893f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Keep all the links to local tab data in one place.
1903f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  class TabLinks {
1913f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen   public:
1923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // To support usage as second value in maps we need default and copy
1933f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // constructors.
1943f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    TabLinks()
1953f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        : sync_id_(0),
1963f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen          session_tab_(NULL),
1973f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen          tab_(NULL) {}
1983f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1993f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // We only ever have either a SessionTab (for foreign tabs), or a
2003f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // TabContents (for local tabs).
2013f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    TabLinks(int64 sync_id, const TabContents* tab)
2023f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      : sync_id_(sync_id),
2033f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        session_tab_(NULL) {
2043f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      tab_ = const_cast<TabContents*>(tab);
2053f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    }
2063f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    TabLinks(int64 sync_id, const SessionTab* session_tab)
2073f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      : sync_id_(sync_id),
2083f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        tab_(NULL) {
2093f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      session_tab_ = const_cast<SessionTab*>(session_tab);
2103f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    }
2113f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2123f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    inline int64 sync_id() const { return sync_id_; }
2133f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    inline const SessionTab* session_tab() const { return session_tab_; }
2143f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    inline const TabContents* tab() const { return tab_; }
2153f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen   private:
2163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    int64 sync_id_;
2173f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    SessionTab* session_tab_;
2183f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    TabContents* tab_;
2193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  };
2203f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2213f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // A pool for managing free/used tab sync nodes. Performs lazy creation
2223f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // of sync nodes when necessary.
2233f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  class TabNodePool {
2243f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen   public:
2253f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    explicit TabNodePool(ProfileSyncService* sync_service);
22672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    ~TabNodePool();
2273f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2283f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // Add a previously allocated tab sync node to our pool. Increases the size
2293f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // of tab_syncid_pool_ by one and marks the new tab node as free.
2303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // Note: this should only be called when we discover tab sync nodes from
2313f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // previous sessions, not for freeing tab nodes we created through
2323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // GetFreeTabNode (use FreeTabNode below for that).
2333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    void AddTabNode(int64 sync_id);
2343f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2353f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // Returns the sync_id for the next free tab node. If none are available,
2363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // creates a new tab node.
2373f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // Note: We make use of the following "id's"
2383f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // - a sync_id: an int64 used in |sync_api::InitByIdLookup|
2393f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // - a tab_id: created by session service, unique to this client
2403f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // - a tab_node_id: the id for a particular sync tab node. This is used
2413f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    //   to generate the sync tab node tag through:
2423f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    //       tab_tag = StringPrintf("%s_%ui", local_session_tag, tab_node_id);
2433f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // tab_node_id and sync_id are both unique to a particular sync node. The
2443f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // difference is that tab_node_id is controlled by the model associator and
2453f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // is used when creating a new sync node, which returns the sync_id, created
2463f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // by the sync db.
2473f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    int64 GetFreeTabNode();
2483f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2493f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // Return a tab node to our free pool.
2503f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // Note: the difference between FreeTabNode and AddTabNode is that
2513f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // FreeTabNode does not modify the size of |tab_syncid_pool_|, while
2523f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // AddTabNode increases it by one. In the case of FreeTabNode, the size of
2533f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // the |tab_syncid_pool_| should always be equal to the amount of tab nodes
2543f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // associated with this machine.
2553f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    void FreeTabNode(int64 sync_id);
2563f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2573f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // Clear tab pool.
2583f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    inline void clear() { tab_syncid_pool_.clear(); }
2593f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2603f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // Return the number of tab nodes this client currently has allocated
2613f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // (including both free and used nodes)
2623f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    inline size_t capacity() const { return tab_syncid_pool_.size(); }
2633f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2643f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // Return empty status (all tab nodes are in use).
2653f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    inline bool empty() const { return tab_pool_fp_ == -1; }
2663f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2673f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // Return full status (no tab nodes are in use).
2683f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    inline bool full() {
2693f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      return tab_pool_fp_ == static_cast<int64>(tab_syncid_pool_.size())-1;
2703f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    }
2713f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2723f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    inline void set_machine_tag(const std::string& machine_tag) {
2733f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      machine_tag_ = machine_tag;
2743f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    }
2753f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen   private:
2763f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // Pool of all available syncid's for tab's we have created.
2773f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    std::vector<int64> tab_syncid_pool_;
2783f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2793f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // Free pointer for tab pool. Only those node id's, up to and including the
2803f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // one indexed by the free pointer, are valid and free. The rest of the
2813f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // |tab_syncid_pool_| is invalid because the nodes are in use.
2823f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // To get the next free node, use tab_syncid_pool_[tab_pool_fp_--].
2833f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    int64 tab_pool_fp_;
2843f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2853f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // The machiine tag associated with this tab pool. Used in the title of new
2863f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // sync nodes.
2873f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    std::string machine_tag_;
2883f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2893f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // Our sync service profile (for making changes to the sync db)
2903f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    ProfileSyncService* sync_service_;
2913f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    DISALLOW_COPY_AND_ASSIGN(TabNodePool);
2933f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  };
2943f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2953f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Datatypes for accessing local tab data.
2963f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  typedef std::map<SessionID::id_type, TabLinks> TabLinksMap;
2973f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2983f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Delete all foreign session/window/tab objects allocated dynamically.
2993f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // This is comprised of ForeignSession*, IDToSessionTabMap*, and any orphaned
3003f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // SessionTab*'s.
3013f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  void DeleteForeignSessions();
3023f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
3033f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Determine if a window is of a type we're interested in syncing.
3043f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  static bool ShouldSyncWindowType(const Browser::Type& type);
3053f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
3063f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Build a sync tag from tab_node_id.
3073f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  static inline std::string TabIdToTag(
3083f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      const std::string machine_tag,
3093f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      size_t tab_node_id) {
310dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return StringPrintf("%s %"PRIuS"",
311dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        machine_tag.c_str(), tab_node_id);
3123f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  }
313bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
314bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Initializes the tag corresponding to this machine.
3153f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  void InitializeCurrentMachineTag(sync_api::WriteTransaction* trans);
316bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
3173f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Updates the server data based upon the current client session.  If no node
3183f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // corresponding to this machine exists in the sync model, one is created.
3193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  void UpdateSyncModelDataFromClient();
320bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
3213f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Pulls the current sync model from the sync database and returns true upon
3223f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // update of the client model. Will associate any foreign sessions as well as
3233f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // keep track of any local tab nodes, adding them to our free tab node pool.
3243f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  bool UpdateAssociationsFromSyncModel(const sync_api::ReadNode& root,
3253f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                       const sync_api::BaseTransaction* trans);
326bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
3273f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Fills a tab sync node with data from a TabContents object.
3283f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // (from a local navigation event)
329dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  bool WriteTabContentsToSyncModel(const Browser& browser,
330dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                   const TabContents& tab,
3313f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                   const int64 sync_id,
3323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                   sync_api::WriteTransaction* trans);
3333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
3343f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Used to populate a session window from the session specifics window
3353f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // provided. Tracks any foreign session data created through |tracker|.
3363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  static void PopulateSessionWindowFromSpecifics(
337ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      const std::string& foreign_session_tag,
3383f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      const sync_pb::SessionWindow& window,
3393f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      const int64 mtime,
3403f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      SessionWindow* session_window,
3413f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      ForeignSessionTracker* tracker);
3423f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
3433f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Used to populate a session tab from the session specifics tab provided.
3443f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  static void PopulateSessionTabFromSpecifics(const sync_pb::SessionTab& tab,
3453f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                              const int64 mtime,
3463f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                              SessionTab* session_tab);
347bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
3483f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Used to populate a session tab from the session specifics tab provided.
3493f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  static void AppendSessionTabNavigation(
3503f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen     const sync_pb::TabNavigation& navigation,
3513f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen     std::vector<TabNavigation>* navigations);
3523f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
3533f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Populates the navigation portion of the session specifics.
3543f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  static void PopulateSessionSpecificsNavigation(
3553f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen     const TabNavigation* navigation,
3563f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen     sync_pb::TabNavigation* tab_navigation);
3573f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
3583f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Returns the session service from |sync_service_|.
3593f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  SessionService* GetSessionService();
360bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
361bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Internal method used in the callback to obtain the current session.
362bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // We don't own |windows|.
363bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  void OnGotSession(int handle, std::vector<SessionWindow*>* windows);
364bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
3653f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Populate a session specifics header from a list of SessionWindows
3663f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  void PopulateSessionSpecificsHeader(
3673f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      const std::vector<SessionWindow*>& windows,
3683f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      sync_pb::SessionHeader* header_s);
369bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
3703f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Populates the window portion of the session specifics.
3713f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  void PopulateSessionSpecificsWindow(const SessionWindow& window,
3723f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                      sync_pb::SessionWindow* session_window);
373bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
3743f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Syncs all the tabs in |window| with the local sync db. Will allocate tab
3753f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // nodes if needed.
3763f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  bool SyncLocalWindowToSyncModel(const SessionWindow& window);
3773f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
3783f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Fills a tab sync node with data from a SessionTab object.
3793f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // (from ReadCurrentSessions)
3803f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  bool WriteSessionTabToSyncModel(const SessionTab& tab,
3813f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                  const int64 sync_id,
3823f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                  sync_api::WriteTransaction* trans);
3833f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
3843f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Populates the tab portion of the session specifics.
3853f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  void PopulateSessionSpecificsTab(const SessionTab& tab,
3863f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                   sync_pb::SessionTab* session_tab);
3873f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
3883f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Local client name.
389bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  std::string current_machine_tag_;
390bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
3913f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Pool of all used/available sync nodes associated with tabs.
3923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  TabNodePool tab_pool_;
3933f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
3943f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // SyncID for the sync node containing all the window information for this
3953f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // client.
3963f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  int64 local_session_syncid_;
3973f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
3983f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Mapping of current open (local) tabs to their sync identifiers.
3993f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  TabLinksMap tab_map_;
4003f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
4013f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  ForeignSessionTracker foreign_session_tracker_;
402731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
403bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Weak pointer.
404bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  ProfileSyncService* sync_service_;
405bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
406bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Consumer used to obtain the current session.
407bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  CancelableRequestConsumer consumer_;
408bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
409dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // To avoid certain checks not applicable to tests.
410dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  bool setup_for_test_;
411dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
412bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  DISALLOW_COPY_AND_ASSIGN(SessionModelAssociator);
413bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen};
414bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
415bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}  // namespace browser_sync
416bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
417bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#endif  // CHROME_BROWSER_SYNC_GLUE_SESSION_MODEL_ASSOCIATOR_H_
418