| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "sync/internal_api/public/base_node.h" | 5 #include "sync/internal_api/public/base_node.h" |
| 6 | 6 |
| 7 #include <stack> | 7 #include <stack> |
| 8 | 8 |
| 9 #include "base/base64.h" | |
| 10 #include "base/sha1.h" | |
| 11 #include "base/string_number_conversions.h" | 9 #include "base/string_number_conversions.h" |
| 12 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
| 13 #include "base/values.h" | 11 #include "base/values.h" |
| 14 #include "sync/internal_api/public/base_transaction.h" | 12 #include "sync/internal_api/public/base_transaction.h" |
| 15 #include "sync/internal_api/syncapi_internal.h" | 13 #include "sync/internal_api/syncapi_internal.h" |
| 16 #include "sync/protocol/app_specifics.pb.h" | 14 #include "sync/protocol/app_specifics.pb.h" |
| 17 #include "sync/protocol/autofill_specifics.pb.h" | 15 #include "sync/protocol/autofill_specifics.pb.h" |
| 18 #include "sync/protocol/bookmark_specifics.pb.h" | 16 #include "sync/protocol/bookmark_specifics.pb.h" |
| 19 #include "sync/protocol/extension_specifics.pb.h" | 17 #include "sync/protocol/extension_specifics.pb.h" |
| 20 #include "sync/protocol/nigori_specifics.pb.h" | 18 #include "sync/protocol/nigori_specifics.pb.h" |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 EndsWithSpace(server_name)) { | 56 EndsWithSpace(server_name)) { |
| 59 --length_to_copy; | 57 --length_to_copy; |
| 60 } | 58 } |
| 61 *out = std::string(server_name.c_str(), length_to_copy); | 59 *out = std::string(server_name.c_str(), length_to_copy); |
| 62 } | 60 } |
| 63 | 61 |
| 64 BaseNode::BaseNode() : password_data_(new sync_pb::PasswordSpecificsData) {} | 62 BaseNode::BaseNode() : password_data_(new sync_pb::PasswordSpecificsData) {} |
| 65 | 63 |
| 66 BaseNode::~BaseNode() {} | 64 BaseNode::~BaseNode() {} |
| 67 | 65 |
| 68 std::string BaseNode::GenerateSyncableHash( | |
| 69 ModelType model_type, const std::string& client_tag) { | |
| 70 // Blank PB with just the field in it has termination symbol, | |
| 71 // handy for delimiter. | |
| 72 sync_pb::EntitySpecifics serialized_type; | |
| 73 AddDefaultFieldValue(model_type, &serialized_type); | |
| 74 std::string hash_input; | |
| 75 serialized_type.AppendToString(&hash_input); | |
| 76 hash_input.append(client_tag); | |
| 77 | |
| 78 std::string encode_output; | |
| 79 CHECK(base::Base64Encode(base::SHA1HashString(hash_input), &encode_output)); | |
| 80 return encode_output; | |
| 81 } | |
| 82 | |
| 83 bool BaseNode::DecryptIfNecessary() { | 66 bool BaseNode::DecryptIfNecessary() { |
| 84 if (!GetEntry()->Get(syncable::UNIQUE_SERVER_TAG).empty()) | 67 if (!GetEntry()->Get(syncable::UNIQUE_SERVER_TAG).empty()) |
| 85 return true; // Ignore unique folders. | 68 return true; // Ignore unique folders. |
| 86 const sync_pb::EntitySpecifics& specifics = | 69 const sync_pb::EntitySpecifics& specifics = |
| 87 GetEntry()->Get(syncable::SPECIFICS); | 70 GetEntry()->Get(syncable::SPECIFICS); |
| 88 if (specifics.has_password()) { | 71 if (specifics.has_password()) { |
| 89 // Passwords have their own legacy encryption structure. | 72 // Passwords have their own legacy encryption structure. |
| 90 scoped_ptr<sync_pb::PasswordSpecificsData> data(DecryptPasswordSpecifics( | 73 scoped_ptr<sync_pb::PasswordSpecificsData> data(DecryptPasswordSpecifics( |
| 91 specifics, GetTransaction()->GetCryptographer())); | 74 specifics, GetTransaction()->GetCryptographer())); |
| 92 if (!data.get()) { | 75 if (!data.get()) { |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 return result; | 188 return result; |
| 206 } | 189 } |
| 207 | 190 |
| 208 bool BaseNode::HasChildren() const { | 191 bool BaseNode::HasChildren() const { |
| 209 syncable::Directory* dir = GetTransaction()->GetDirectory(); | 192 syncable::Directory* dir = GetTransaction()->GetDirectory(); |
| 210 syncable::BaseTransaction* trans = GetTransaction()->GetWrappedTrans(); | 193 syncable::BaseTransaction* trans = GetTransaction()->GetWrappedTrans(); |
| 211 return dir->HasChildren(trans, GetEntry()->Get(syncable::ID)); | 194 return dir->HasChildren(trans, GetEntry()->Get(syncable::ID)); |
| 212 } | 195 } |
| 213 | 196 |
| 214 int64 BaseNode::GetPredecessorId() const { | 197 int64 BaseNode::GetPredecessorId() const { |
| 215 syncable::Id id_string = GetEntry()->Get(syncable::PREV_ID); | 198 syncable::Id id_string = GetEntry()->GetPredecessorId(); |
| 216 if (id_string.IsRoot()) | 199 if (id_string.IsRoot()) |
| 217 return kInvalidId; | 200 return kInvalidId; |
| 218 return IdToMetahandle(GetTransaction()->GetWrappedTrans(), id_string); | 201 return IdToMetahandle(GetTransaction()->GetWrappedTrans(), id_string); |
| 219 } | 202 } |
| 220 | 203 |
| 221 int64 BaseNode::GetSuccessorId() const { | 204 int64 BaseNode::GetSuccessorId() const { |
| 222 syncable::Id id_string = GetEntry()->Get(syncable::NEXT_ID); | 205 syncable::Id id_string = GetEntry()->GetSuccessorId(); |
| 223 if (id_string.IsRoot()) | 206 if (id_string.IsRoot()) |
| 224 return kInvalidId; | 207 return kInvalidId; |
| 225 return IdToMetahandle(GetTransaction()->GetWrappedTrans(), id_string); | 208 return IdToMetahandle(GetTransaction()->GetWrappedTrans(), id_string); |
| 226 } | 209 } |
| 227 | 210 |
| 228 int64 BaseNode::GetFirstChildId() const { | 211 int64 BaseNode::GetFirstChildId() const { |
| 229 syncable::Directory* dir = GetTransaction()->GetDirectory(); | 212 syncable::Id id_string = GetEntry()->GetFirstChildId(); |
| 230 syncable::BaseTransaction* trans = GetTransaction()->GetWrappedTrans(); | |
| 231 syncable::Id id_string; | |
| 232 // TODO(akalin): Propagate up the error further (see | |
| 233 // http://crbug.com/100907). | |
| 234 CHECK(dir->GetFirstChildId(trans, | |
| 235 GetEntry()->Get(syncable::ID), &id_string)); | |
| 236 if (id_string.IsRoot()) | 213 if (id_string.IsRoot()) |
| 237 return kInvalidId; | 214 return kInvalidId; |
| 238 return IdToMetahandle(GetTransaction()->GetWrappedTrans(), id_string); | 215 return IdToMetahandle(GetTransaction()->GetWrappedTrans(), id_string); |
| 239 } | 216 } |
| 240 | 217 |
| 241 int BaseNode::GetTotalNodeCount() const { | 218 int BaseNode::GetTotalNodeCount() const { |
| 242 syncable::Directory* dir = GetTransaction()->GetDirectory(); | |
| 243 syncable::BaseTransaction* trans = GetTransaction()->GetWrappedTrans(); | 219 syncable::BaseTransaction* trans = GetTransaction()->GetWrappedTrans(); |
| 244 | 220 |
| 245 int count = 1; // Start with one to include the node itself. | 221 int count = 1; // Start with one to include the node itself. |
| 246 | 222 |
| 247 std::stack<int64> stack; | 223 std::stack<int64> stack; |
| 248 stack.push(GetFirstChildId()); | 224 stack.push(GetFirstChildId()); |
| 249 while (!stack.empty()) { | 225 while (!stack.empty()) { |
| 250 int64 handle = stack.top(); | 226 int64 handle = stack.top(); |
| 251 stack.pop(); | 227 stack.pop(); |
| 252 if (handle == kInvalidId) | 228 if (handle == kInvalidId) |
| 253 continue; | 229 continue; |
| 254 count++; | 230 count++; |
| 255 syncable::Entry entry(trans, syncable::GET_BY_HANDLE, handle); | 231 syncable::Entry entry(trans, syncable::GET_BY_HANDLE, handle); |
| 256 if (!entry.good()) | 232 if (!entry.good()) |
| 257 continue; | 233 continue; |
| 258 syncable::Id id = entry.Get(syncable::ID); | 234 syncable::Id id = entry.Get(syncable::ID); |
| 259 syncable::Id child_id; | 235 syncable::Id successor_id = entry.GetSuccessorId(); |
| 260 if (dir->GetFirstChildId(trans, id, &child_id) && !child_id.IsRoot()) | |
| 261 stack.push(IdToMetahandle(trans, child_id)); | |
| 262 syncable::Id successor_id = entry.Get(syncable::NEXT_ID); | |
| 263 if (!successor_id.IsRoot()) | 236 if (!successor_id.IsRoot()) |
| 264 stack.push(IdToMetahandle(trans, successor_id)); | 237 stack.push(IdToMetahandle(trans, successor_id)); |
| 238 if (!entry.Get(syncable::IS_DIR)) |
| 239 continue; |
| 240 syncable::Id child_id = entry.GetFirstChildId(); |
| 241 if (!child_id.IsRoot()) |
| 242 stack.push(IdToMetahandle(trans, child_id)); |
| 265 } | 243 } |
| 266 return count; | 244 return count; |
| 267 } | 245 } |
| 268 | 246 |
| 269 DictionaryValue* BaseNode::GetSummaryAsValue() const { | 247 DictionaryValue* BaseNode::GetSummaryAsValue() const { |
| 270 DictionaryValue* node_info = new DictionaryValue(); | 248 DictionaryValue* node_info = new DictionaryValue(); |
| 271 node_info->SetString("id", base::Int64ToString(GetId())); | 249 node_info->SetString("id", base::Int64ToString(GetId())); |
| 272 node_info->SetBoolean("isFolder", GetIsFolder()); | 250 node_info->SetBoolean("isFolder", GetIsFolder()); |
| 273 node_info->SetString("title", GetTitle()); | 251 node_info->SetString("title", GetTitle()); |
| 274 node_info->Set("type", ModelTypeToValue(GetModelType())); | 252 node_info->Set("type", ModelTypeToValue(GetModelType())); |
| 275 return node_info; | 253 return node_info; |
| 276 } | 254 } |
| 277 | 255 |
| 278 DictionaryValue* BaseNode::GetDetailsAsValue() const { | 256 DictionaryValue* BaseNode::GetDetailsAsValue() const { |
| 279 DictionaryValue* node_info = GetSummaryAsValue(); | 257 DictionaryValue* node_info = GetSummaryAsValue(); |
| 280 node_info->SetString( | 258 node_info->SetString( |
| 281 "modificationTime", | 259 "modificationTime", |
| 282 GetTimeDebugString(GetModificationTime())); | 260 GetTimeDebugString(GetModificationTime())); |
| 283 node_info->SetString("parentId", base::Int64ToString(GetParentId())); | 261 node_info->SetString("parentId", base::Int64ToString(GetParentId())); |
| 284 // Specifics are already in the Entry value, so no need to duplicate | 262 // Specifics are already in the Entry value, so no need to duplicate |
| 285 // it here. | 263 // it here. |
| 286 node_info->SetString("externalId", | 264 node_info->SetString("externalId", |
| 287 base::Int64ToString(GetExternalId())); | 265 base::Int64ToString(GetExternalId())); |
| 288 node_info->SetString("predecessorId", | |
| 289 base::Int64ToString(GetPredecessorId())); | |
| 290 node_info->SetString("successorId", | |
| 291 base::Int64ToString(GetSuccessorId())); | |
| 292 node_info->SetString("firstChildId", | |
| 293 base::Int64ToString(GetFirstChildId())); | |
| 294 node_info->Set("entry", | 266 node_info->Set("entry", |
| 295 GetEntry()->ToValue(GetTransaction()->GetCryptographer())); | 267 GetEntry()->ToValue(GetTransaction()->GetCryptographer())); |
| 296 return node_info; | 268 return node_info; |
| 297 } | 269 } |
| 298 | 270 |
| 299 int64 BaseNode::GetExternalId() const { | 271 int64 BaseNode::GetExternalId() const { |
| 300 return GetEntry()->Get(syncable::LOCAL_EXTERNAL_ID); | 272 return GetEntry()->Get(syncable::LOCAL_EXTERNAL_ID); |
| 301 } | 273 } |
| 302 | 274 |
| 303 const sync_pb::AppSpecifics& BaseNode::GetAppSpecifics() const { | 275 const sync_pb::AppSpecifics& BaseNode::GetAppSpecifics() const { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 372 const sync_pb::EntitySpecifics& specifics) { | 344 const sync_pb::EntitySpecifics& specifics) { |
| 373 ModelType type = GetModelTypeFromSpecifics(specifics); | 345 ModelType type = GetModelTypeFromSpecifics(specifics); |
| 374 DCHECK_NE(UNSPECIFIED, type); | 346 DCHECK_NE(UNSPECIFIED, type); |
| 375 if (GetModelType() != UNSPECIFIED) { | 347 if (GetModelType() != UNSPECIFIED) { |
| 376 DCHECK_EQ(GetModelType(), type); | 348 DCHECK_EQ(GetModelType(), type); |
| 377 } | 349 } |
| 378 unencrypted_data_.CopyFrom(specifics); | 350 unencrypted_data_.CopyFrom(specifics); |
| 379 } | 351 } |
| 380 | 352 |
| 381 } // namespace syncer | 353 } // namespace syncer |
| OLD | NEW |