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 SYNC_INTERNAL_API_PUBLIC_BASE_NODE_H_
6 #define SYNC_INTERNAL_API_PUBLIC_BASE_NODE_H_
11 #include "base/basictypes.h"
12 #include "base/gtest_prod_util.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/time/time.h"
15 #include "sync/base/sync_export.h"
16 #include "sync/internal_api/public/base/model_type.h"
17 #include "sync/protocol/sync.pb.h"
20 // Forward declarations of internal class types so that sync API objects
21 // may have opaque pointers to these types.
23 class DictionaryValue;
28 class AutofillSpecifics;
29 class AutofillProfileSpecifics;
30 class BookmarkSpecifics;
31 class EntitySpecifics;
32 class ExtensionSpecifics;
33 class SessionSpecifics;
34 class NigoriSpecifics;
35 class PreferenceSpecifics;
36 class PasswordSpecificsData;
38 class TypedUrlSpecifics;
43 class BaseTransaction;
46 class BaseTransaction;
50 // A valid BaseNode will never have an ID of zero.
51 static const int64 kInvalidId = 0;
53 // BaseNode wraps syncable::Entry, and corresponds to a single object's state.
54 // This, like syncable::Entry, is intended for use on the stack. A valid
55 // transaction is necessary to create a BaseNode or any of its children.
56 // Unlike syncable::Entry, a sync API BaseNode is identified primarily by its
57 // int64 metahandle, which we call an ID here.
58 class SYNC_EXPORT BaseNode {
60 // Enumerates the possible outcomes of trying to initialize a sync node.
61 enum InitByLookupResult {
63 // Could not find an entry matching the lookup criteria.
64 INIT_FAILED_ENTRY_NOT_GOOD,
65 // Found an entry, but it is already deleted.
66 INIT_FAILED_ENTRY_IS_DEL,
67 // Found an entry, but was unable to decrypt.
68 INIT_FAILED_DECRYPT_IF_NECESSARY,
69 // A precondition was not met for calling init, such as legal input
71 INIT_FAILED_PRECONDITION,
74 // All subclasses of BaseNode must provide a way to initialize themselves by
75 // doing an ID lookup. Returns false on failure. An invalid or deleted
76 // ID will result in failure.
77 virtual InitByLookupResult InitByIdLookup(int64 id) = 0;
79 // All subclasses of BaseNode must also provide a way to initialize themselves
80 // by doing a client tag lookup. Returns false on failure. A deleted node
82 virtual InitByLookupResult InitByClientTagLookup(
84 const std::string& tag) = 0;
86 // Each object is identified by a 64-bit id (internally, the syncable
87 // metahandle). These ids are strictly local handles. They will persist
88 // on this client, but the same object on a different client may have a
89 // different ID value.
90 virtual int64 GetId() const;
92 // Returns the modification time of the object.
93 base::Time GetModificationTime() const;
95 // Nodes are hierarchically arranged into a single-rooted tree.
96 // InitByRootLookup on ReadNode allows access to the root. GetParentId is
97 // how you find a node's parent.
98 int64 GetParentId() const;
100 // Nodes are either folders or not. This corresponds to the IS_DIR property
101 // of syncable::Entry.
102 bool GetIsFolder() const;
104 // Returns the title of the object.
105 // Uniqueness of the title is not enforced on siblings -- it is not an error
106 // for two children to share a title.
107 std::string GetTitle() const;
109 // Returns the model type of this object. The model type is set at node
110 // creation time and is expected never to change.
111 ModelType GetModelType() const;
113 // Getter specific to the BOOKMARK datatype. Returns protobuf
114 // data. Can only be called if GetModelType() == BOOKMARK.
115 const sync_pb::BookmarkSpecifics& GetBookmarkSpecifics() const;
117 // Getter specific to the APPS datatype. Returns protobuf
118 // data. Can only be called if GetModelType() == APPS.
119 const sync_pb::AppSpecifics& GetAppSpecifics() const;
121 // Getter specific to the AUTOFILL datatype. Returns protobuf
122 // data. Can only be called if GetModelType() == AUTOFILL.
123 const sync_pb::AutofillSpecifics& GetAutofillSpecifics() const;
125 virtual const sync_pb::AutofillProfileSpecifics&
126 GetAutofillProfileSpecifics() const;
128 // Getter specific to the NIGORI datatype. Returns protobuf
129 // data. Can only be called if GetModelType() == NIGORI.
130 const sync_pb::NigoriSpecifics& GetNigoriSpecifics() const;
132 // Getter specific to the PASSWORD datatype. Returns protobuf
133 // data. Can only be called if GetModelType() == PASSWORD.
134 const sync_pb::PasswordSpecificsData& GetPasswordSpecifics() const;
136 // Getter specific to the PREFERENCE datatype. Returns protobuf
137 // data. Can only be called if GetModelType() == PREFERENCE.
138 const sync_pb::PreferenceSpecifics& GetPreferenceSpecifics() const;
140 // Getter specific to the THEME datatype. Returns protobuf
141 // data. Can only be called if GetModelType() == THEME.
142 const sync_pb::ThemeSpecifics& GetThemeSpecifics() const;
144 // Getter specific to the TYPED_URLS datatype. Returns protobuf
145 // data. Can only be called if GetModelType() == TYPED_URLS.
146 const sync_pb::TypedUrlSpecifics& GetTypedUrlSpecifics() const;
148 // Getter specific to the EXTENSIONS datatype. Returns protobuf
149 // data. Can only be called if GetModelType() == EXTENSIONS.
150 const sync_pb::ExtensionSpecifics& GetExtensionSpecifics() const;
152 // Getter specific to the SESSIONS datatype. Returns protobuf
153 // data. Can only be called if GetModelType() == SESSIONS.
154 const sync_pb::SessionSpecifics& GetSessionSpecifics() const;
156 // Getter specific to the MANAGED_USER_SETTINGS datatype. Returns protobuf
157 // data. Can only be called if GetModelType() == MANAGED_USER_SETTINGS.
158 const sync_pb::ManagedUserSettingSpecifics&
159 GetManagedUserSettingSpecifics() const;
161 // Getter specific to the MANAGED_USERS datatype. Returns protobuf data.
162 // Can only be called if GetModelType() == MANAGED_USERS.
163 const sync_pb::ManagedUserSpecifics& GetManagedUserSpecifics() const;
165 // Getter specific to the DEVICE_INFO datatype. Returns protobuf
166 // data. Can only be called if GetModelType() == DEVICE_INFO.
167 const sync_pb::DeviceInfoSpecifics& GetDeviceInfoSpecifics() const;
169 // Getter specific to the EXPERIMENTS datatype. Returns protobuf
170 // data. Can only be called if GetModelType() == EXPERIMENTS.
171 const sync_pb::ExperimentsSpecifics& GetExperimentsSpecifics() const;
173 // Getter specific to the PRIORITY_PREFERENCE datatype. Returns protobuf
174 // data. Can only be called if GetModelType() == PRIORITY_PREFERENCE.
175 const sync_pb::PriorityPreferenceSpecifics&
176 GetPriorityPreferenceSpecifics() const;
178 const sync_pb::EntitySpecifics& GetEntitySpecifics() const;
180 // Returns the local external ID associated with the node.
181 int64 GetExternalId() const;
183 // Returns true iff this node has children.
184 bool HasChildren() const;
186 // Return the ID of the node immediately before this in the sibling order.
187 // For the first node in the ordering, return 0.
188 int64 GetPredecessorId() const;
190 // Return the ID of the node immediately after this in the sibling order.
191 // For the last node in the ordering, return 0.
192 int64 GetSuccessorId() const;
194 // Return the ID of the first child of this node. If this node has no
195 // children, return 0.
196 int64 GetFirstChildId() const;
198 // Returns the IDs of the children of this node.
199 // If this type supports user-defined positions the returned IDs will be in
200 // the correct order.
201 void GetChildIds(std::vector<int64>* result) const;
203 // Returns the total number of nodes including and beneath this node.
204 // Recursively iterates through all children.
205 int GetTotalNodeCount() const;
207 // Returns this item's position within its parent.
208 // Do not call this function on items that do not support positioning
209 // (ie. non-bookmarks).
210 int GetPositionIndex() const;
212 // These virtual accessors provide access to data members of derived classes.
213 virtual const syncable::Entry* GetEntry() const = 0;
214 virtual const BaseTransaction* GetTransaction() const = 0;
216 // Dumps a summary of node info into a DictionaryValue and returns it.
217 // Transfers ownership of the DictionaryValue to the caller.
218 base::DictionaryValue* GetSummaryAsValue() const;
220 // Dumps all node details into a DictionaryValue and returns it.
221 // Transfers ownership of the DictionaryValue to the caller.
222 base::DictionaryValue* GetDetailsAsValue() const;
228 // Determines whether part of the entry is encrypted, and if so attempts to
229 // decrypt it. Unless decryption is necessary and fails, this will always
230 // return |true|. If the contents are encrypted, the decrypted data will be
231 // stored in |unencrypted_data_|.
232 // This method is invoked once when the BaseNode is initialized.
233 bool DecryptIfNecessary();
235 // Returns the unencrypted specifics associated with |entry|. If |entry| was
236 // not encrypted, it directly returns |entry|'s EntitySpecifics. Otherwise,
237 // returns |unencrypted_data_|.
238 const sync_pb::EntitySpecifics& GetUnencryptedSpecifics(
239 const syncable::Entry* entry) const;
241 // Copy |specifics| into |unencrypted_data_|.
242 void SetUnencryptedSpecifics(const sync_pb::EntitySpecifics& specifics);
245 // Have to friend the test class as well to allow member functions to access
246 // protected/private BaseNode methods.
247 friend class SyncManagerTest;
248 FRIEND_TEST_ALL_PREFIXES(SyncApiTest, GenerateSyncableHash);
249 FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, UpdateEntryWithEncryption);
250 FRIEND_TEST_ALL_PREFIXES(SyncManagerTest,
251 UpdatePasswordSetEntitySpecificsNoChange);
252 FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, UpdatePasswordSetPasswordSpecifics);
253 FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, UpdatePasswordNewPassphrase);
254 FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, UpdatePasswordReencryptEverything);
255 FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, SetBookmarkTitle);
256 FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, SetBookmarkTitleWithEncryption);
257 FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, SetNonBookmarkTitle);
258 FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, SetNonBookmarkTitleWithEncryption);
259 FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, SetPreviouslyEncryptedSpecifics);
260 FRIEND_TEST_ALL_PREFIXES(SyncManagerTest, IncrementTransactionVersion);
262 void* operator new(size_t size); // Node is meant for stack use only.
264 // A holder for the unencrypted data stored in an encrypted node.
265 sync_pb::EntitySpecifics unencrypted_data_;
267 // Same as |unencrypted_data_|, but for legacy password encryption.
268 scoped_ptr<sync_pb::PasswordSpecificsData> password_data_;
270 DISALLOW_COPY_AND_ASSIGN(BaseNode);
273 } // namespace syncer
275 #endif // SYNC_INTERNAL_API_PUBLIC_BASE_NODE_H_