session_model_associator.h revision 21d179b334e59e9a3bfcaed4c4430bef1bc5759d
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#ifndef CHROME_BROWSER_SYNC_GLUE_SESSION_MODEL_ASSOCIATOR_H_
6#define CHROME_BROWSER_SYNC_GLUE_SESSION_MODEL_ASSOCIATOR_H_
7#pragma once
8
9#include <string>
10#include <vector>
11
12#include "base/basictypes.h"
13#include "base/gtest_prod_util.h"
14#include "base/observer_list.h"
15#include "base/scoped_vector.h"
16#include "chrome/browser/sessions/session_service.h"
17#include "chrome/browser/sessions/session_types.h"
18#include "chrome/browser/sync/engine/syncapi.h"
19#include "chrome/browser/sync/glue/model_associator.h"
20#include "chrome/browser/sync/protocol/session_specifics.pb.h"
21#include "chrome/browser/sync/syncable/model_type.h"
22#include "chrome/common/notification_registrar.h"
23
24class Profile;
25class ProfileSyncService;
26
27namespace sync_api {
28class ReadNode;
29class WriteNode;
30class WriteTransaction;
31}  // namespace sync_api
32
33namespace sync_pb {
34class SessionSpecifics;
35}  // namespace sync_pb
36
37namespace browser_sync {
38
39static const char kSessionsTag[] = "google_chrome_sessions";
40
41// Contains all logic for associating the Chrome sessions model and
42// the sync sessions model.
43// In the case of sessions, our local model is nothing but a buffer (specifics_)
44// that gets overwritten everytime there is an update. From it, we build a new
45// foreign session windows list each time |GetSessionData| is called by the
46// ForeignSessionHandler.
47class SessionModelAssociator : public PerDataTypeAssociatorInterface<
48    sync_pb::SessionSpecifics, std::string>, public NonThreadSafe {
49 public:
50
51  // Does not take ownership of sync_service.
52  explicit SessionModelAssociator(ProfileSyncService* sync_service);
53  virtual ~SessionModelAssociator();
54
55  // AssociatorInterface and PerDataTypeAssociator Interface implementation.
56  virtual void AbortAssociation() {
57    // No implementation needed, this associator runs on the main
58    // thread.
59  }
60
61  // Dummy method, we do everything all-at-once in UpdateFromSyncModel.
62  virtual void Associate(const sync_pb::SessionSpecifics* specifics,
63    int64 sync_id) {
64  }
65
66  // Updates the sync model with the local client data. (calls
67  // UpdateFromSyncModel)
68  virtual bool AssociateModels();
69
70  // The has_nodes out parameter is set to true if the chrome model
71  // has user-created nodes.  The method may return false if an error
72  // occurred.
73  virtual bool ChromeModelHasUserCreatedNodes(bool* has_nodes);
74
75  // Dummy method, we do everything all-at-once in UpdateFromSyncModel.
76  virtual void Disassociate(int64 sync_id) {
77  }
78
79  // Clear specifics_ buffer and notify foreign session handlers.
80  virtual bool DisassociateModels();
81
82  // Returns the chrome session specifics for the given sync id.
83  // Returns NULL if no specifics are found for the given sync id.
84  virtual const sync_pb::SessionSpecifics* GetChromeNodeFromSyncId(
85    int64 sync_id);
86
87  // Returns whether a node with the given permanent tag was found and update
88  // |sync_id| with that node's id.
89  virtual bool GetSyncIdForTaggedNode(const std::string* tag, int64* sync_id);
90
91  // Returns sync id for the given chrome model id.
92  // Returns sync_api::kInvalidId if the sync node is not found for the given
93  // chrome id.
94  virtual int64 GetSyncIdFromChromeId(const std::string& id);
95
96
97  // Initializes the given sync node from the given chrome node id.
98  // Returns false if no sync node was found for the given chrome node id or
99  // if the initialization of sync node fails.
100  virtual bool InitSyncNodeFromChromeId(const std::string& id,
101                                        sync_api::BaseNode* sync_node);
102
103  // The has_nodes out parameter is set to true if the sync model has
104  // nodes other than the permanent tagged nodes.  The method may
105  // return false if an error occurred.
106  virtual bool SyncModelHasUserCreatedNodes(bool* has_nodes);
107
108  // Returns the tag used to uniquely identify this machine's session in the
109  // sync model.
110  std::string GetCurrentMachineTag();
111
112  // Updates the server data based upon the current client session.  If no node
113  // corresponding to this machine exists in the sync model, one is created.
114  void UpdateSyncModelDataFromClient();
115
116  // Pulls the current sync model from the sync database and returns true upon
117  // update of the client model. Called by SessionChangeProcessor.
118  // Note that the specifics_ vector is reset and built from scratch each time.
119  bool UpdateFromSyncModel(const sync_api::BaseTransaction* trans);
120
121  // Helper for UpdateFromSyncModel. Appends sync data to a vector of specifics.
122  bool QuerySyncModel(const sync_api::BaseTransaction* trans,
123      std::vector<const sync_pb::SessionSpecifics*>& specifics);
124
125  // Builds sessions from buffered specifics data
126  bool GetSessionData(std::vector<ForeignSession*>* sessions);
127
128  // Helper method to generate session specifics from session windows.
129  void FillSpecificsFromSessions(std::vector<SessionWindow*>* windows,
130      sync_pb::SessionSpecifics* session);
131
132  // Helper method for converting session specifics to windows.
133  void AppendForeignSessionFromSpecifics(
134      const sync_pb::SessionSpecifics* specifics,
135      std::vector<ForeignSession*>* session);
136
137  // Fills the given empty vector with foreign session windows to restore.
138  // If the vector is returned empty, then the session data could not be
139  // converted back into windows.
140  void AppendForeignSessionWithID(int64 id,
141      std::vector<ForeignSession*>* session,
142      sync_api::BaseTransaction* trans);
143
144  // Returns the syncable model type.
145  static syncable::ModelType model_type() { return syncable::SESSIONS; }
146
147 private:
148  FRIEND_TEST_ALL_PREFIXES(ProfileSyncServiceSessionTest, WriteSessionToNode);
149  FRIEND_TEST_ALL_PREFIXES(ProfileSyncServiceSessionTest,
150                           WriteForeignSessionToNode);
151
152  // Returns the session service from |sync_service_|.
153  SessionService* GetSessionService();
154
155  // Initializes the tag corresponding to this machine.
156  // Note: creates a syncable::BaseTransaction.
157  void InitializeCurrentMachineTag();
158
159  // Populates the navigation portion of the session specifics.
160  void PopulateSessionSpecificsNavigation(const TabNavigation* navigation,
161      sync_pb::TabNavigation* tab_navigation);
162
163  // Populates the tab portion of the session specifics.
164  void PopulateSessionSpecificsTab(const SessionTab* tab,
165      sync_pb::SessionTab* session_tab);
166
167  // Populates the window portion of the session specifics.
168  void PopulateSessionSpecificsWindow(const SessionWindow* window,
169      sync_pb::SessionWindow* session_window);
170
171  // Specifies whether the window has tabs to sync.  The new tab page does not
172  // count.  If no tabs to sync, it returns true, otherwise false;
173  bool WindowHasNoTabsToSync(const SessionWindow* window);
174
175  // Internal method used in the callback to obtain the current session.
176  // We don't own |windows|.
177  void OnGotSession(int handle, std::vector<SessionWindow*>* windows);
178
179  // Used to populate a session tab from the session specifics tab provided.
180  void AppendSessionTabNavigation(std::vector<TabNavigation>* navigations,
181      const sync_pb::TabNavigation* navigation);
182
183  // Used to populate a session tab from the session specifics tab provided.
184  void PopulateSessionTabFromSpecifics(SessionTab* session_tab,
185      const sync_pb::SessionTab* tab, SessionID id);
186
187  // Used to populate a session window from the session specifics window
188  // provided.
189  void PopulateSessionWindowFromSpecifics(SessionWindow* session_window,
190      const sync_pb::SessionWindow* window);
191
192  // Updates the current session on the server.  Creates a node for this machine
193  // if there is not one already.
194  bool UpdateSyncModel(sync_pb::SessionSpecifics* session_data,
195                    sync_api::WriteTransaction* trans,
196                    const sync_api::ReadNode* root);
197  // Stores the machine tag.
198  std::string current_machine_tag_;
199
200  // Stores the current set of foreign session specifics.
201  // Used by ForeignSessionHandler through |GetSessionData|.
202  // Built by |QuerySyncModel| via |UpdateFromSyncModel|.
203  std::vector<const sync_pb::SessionSpecifics*> specifics_;
204
205  // Weak pointer.
206  ProfileSyncService* sync_service_;
207
208  // Consumer used to obtain the current session.
209  CancelableRequestConsumer consumer_;
210
211  DISALLOW_COPY_AND_ASSIGN(SessionModelAssociator);
212};
213
214}  // namespace browser_sync
215
216#endif  // CHROME_BROWSER_SYNC_GLUE_SESSION_MODEL_ASSOCIATOR_H_
217