• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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 // Utility functions manipulating syncable::Entries, intended for use by the
6 // syncer.
7 
8 #ifndef CHROME_BROWSER_SYNC_ENGINE_SYNCER_UTIL_H_
9 #define CHROME_BROWSER_SYNC_ENGINE_SYNCER_UTIL_H_
10 #pragma once
11 
12 #include <set>
13 #include <string>
14 #include <vector>
15 
16 #include "build/build_config.h"
17 #include "chrome/browser/sync/engine/syncer.h"
18 #include "chrome/browser/sync/engine/syncer_types.h"
19 #include "chrome/browser/sync/syncable/syncable.h"
20 #include "chrome/browser/sync/syncable/syncable_id.h"
21 
22 namespace browser_sync {
23 
24 class Cryptographer;
25 class SyncEntity;
26 
27 class SyncerUtil {
28  public:
29   static void ChangeEntryIDAndUpdateChildren(
30       syncable::WriteTransaction* trans,
31       syncable::MutableEntry* entry,
32       const syncable::Id& new_id,
33       syncable::Directory::ChildHandles* children);
34 
35   // Returns the number of unsynced entries.
36   static int GetUnsyncedEntries(syncable::BaseTransaction* trans,
37                                 std::vector<int64> *handles);
38 
39   static void ChangeEntryIDAndUpdateChildren(syncable::WriteTransaction* trans,
40                                              syncable::MutableEntry* entry,
41                                              const syncable::Id& new_id);
42 
43   // If the server sent down a client-tagged entry, or an entry whose
44   // commit response was lost, it is necessary to update a local entry
45   // with an ID that doesn't match the ID of the update.  Here, we
46   // find the ID of such an entry, if it exists.  This function may
47   // determine that |server_entry| should be dropped; if so, it returns
48   // the null ID -- callers must handle this case.  When update application
49   // should proceed normally with a new local entry, this function will
50   // return server_entry.id(); the caller must create an entry with that
51   // ID.  This function does not alter the database.
52   static syncable::Id FindLocalIdToUpdate(
53       syncable::BaseTransaction* trans,
54       const SyncEntity& server_entry);
55 
56   static UpdateAttemptResponse AttemptToUpdateEntry(
57       syncable::WriteTransaction* const trans,
58       syncable::MutableEntry* const entry,
59       ConflictResolver* resolver,
60       Cryptographer* cryptographer);
61 
62   // Pass in name to avoid redundant UTF8 conversion.
63   static void UpdateServerFieldsFromUpdate(
64       syncable::MutableEntry* local_entry,
65       const SyncEntity& server_entry,
66       const std::string& name);
67 
68   // Creates a new Entry iff no Entry exists with the given id.
69   static void CreateNewEntry(syncable::WriteTransaction *trans,
70                              const syncable::Id& id);
71 
72   static bool ServerAndLocalEntriesMatch(syncable::Entry* entry);
73 
74   static void SplitServerInformationIntoNewEntry(
75       syncable::WriteTransaction* trans,
76       syncable::MutableEntry* entry);
77 
78   // This function is called on an entry when we can update the user-facing data
79   // from the server data.
80   static void UpdateLocalDataFromServerData(syncable::WriteTransaction* trans,
81                                             syncable::MutableEntry* entry);
82 
83   static VerifyCommitResult ValidateCommitEntry(syncable::Entry* entry);
84 
85   static VerifyResult VerifyNewEntry(const SyncEntity& update,
86                                      syncable::Entry* target,
87                                      const bool deleted);
88 
89   // Assumes we have an existing entry; check here for updates that break
90   // consistency rules.
91   static VerifyResult VerifyUpdateConsistency(syncable::WriteTransaction* trans,
92                                               const SyncEntity& update,
93                                               syncable::MutableEntry* target,
94                                               const bool deleted,
95                                               const bool is_directory,
96                                               syncable::ModelType model_type);
97 
98   // Assumes we have an existing entry; verify an update that seems to be
99   // expressing an 'undelete'
100   static VerifyResult VerifyUndelete(syncable::WriteTransaction* trans,
101                                      const SyncEntity& update,
102                                      syncable::MutableEntry* target);
103 
104   // Append |item|, followed by a chain of its predecessors selected by
105   // |inclusion_filter|, to the |commit_ids| vector and tag them as included by
106   // storing in the set |inserted_items|.  |inclusion_filter| (typically one of
107   // IS_UNAPPLIED_UPDATE or IS_UNSYNCED) selects which type of predecessors to
108   // include.  Returns true if |item| was added, and false if it was already in
109   // the list.
110   //
111   // Use AddPredecessorsThenItem instead of this method if you want the
112   // item to be the last, rather than first, item appended.
113   static bool AddItemThenPredecessors(
114       syncable::BaseTransaction* trans,
115       syncable::Entry* item,
116       syncable::IndexedBitField inclusion_filter,
117       syncable::MetahandleSet* inserted_items,
118       std::vector<syncable::Id>* commit_ids);
119 
120   // Exactly like AddItemThenPredecessors, except items are appended in the
121   // reverse (and generally more useful) order: a chain of predecessors from
122   // far to near, and finally the item.
123   static void AddPredecessorsThenItem(
124       syncable::BaseTransaction* trans,
125       syncable::Entry* item,
126       syncable::IndexedBitField inclusion_filter,
127       syncable::MetahandleSet* inserted_items,
128       std::vector<syncable::Id>* commit_ids);
129 
130   static void MarkDeletedChildrenSynced(
131       const syncable::ScopedDirLookup &dir,
132       std::set<syncable::Id>* deleted_folders);
133 
134   // Examine the up-to-date predecessors of this item according to the server
135   // position, and then again according to the local position.  Return true
136   // if they match.  For an up-to-date item, this should be the case.
137   static bool ServerAndLocalOrdersMatch(syncable::Entry* entry);
138 
139  private:
140   DISALLOW_IMPLICIT_CONSTRUCTORS(SyncerUtil);
141 };
142 
143 #ifndef OS_WIN
144 
145 // time.h on Linux and Mac both return seconds since the epoch, this should
146 // be converted to milliseconds.
ServerTimeToClientTime(int64 server_time)147 inline int64 ServerTimeToClientTime(int64 server_time) {
148   return server_time / GG_LONGLONG(1000);
149 }
150 
ClientTimeToServerTime(int64 client_time)151 inline int64 ClientTimeToServerTime(int64 client_time) {
152   return client_time * GG_LONGLONG(1000);
153 }
154 
155 // As we truncate server times on the client for posix and on the server for
156 // windows we need two ClientAndServerTimeMatch fucntions.
ClientAndServerTimeMatch(int64 client_time,int64 server_time)157 inline bool ClientAndServerTimeMatch(int64 client_time, int64 server_time) {
158   // Compare at the coarser timescale (client)
159   return client_time == ServerTimeToClientTime(server_time);
160 }
161 #else
162 // The sync server uses Java Times (ms since 1970)
163 // and the client uses FILETIMEs (ns since 1601) so we need to convert
164 // between the timescales.
165 // TODO(sync): Fix this. No need to use two timescales.
ServerTimeToClientTime(int64 server_time)166 inline int64 ServerTimeToClientTime(int64 server_time) {
167   return server_time * GG_LONGLONG(10000) + GG_LONGLONG(116444736000000000);
168 }
169 
ClientTimeToServerTime(int64 client_time)170 inline int64 ClientTimeToServerTime(int64 client_time) {
171   return (client_time - GG_LONGLONG(116444736000000000)) / GG_LONGLONG(10000);
172 }
173 
ClientAndServerTimeMatch(int64 client_time,int64 server_time)174 inline bool ClientAndServerTimeMatch(int64 client_time, int64 server_time) {
175   // Compare at the coarser timescale (server)
176   return ClientTimeToServerTime(client_time) == server_time;
177 }
178 #endif
179 
180 }  // namespace browser_sync
181 
182 #endif  // CHROME_BROWSER_SYNC_ENGINE_SYNCER_UTIL_H_
183