| OLD | NEW |
| 1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2009 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 "chrome/browser/sync/engine/syncapi.h" | 5 #include "chrome/browser/sync/engine/syncapi.h" |
| 6 | 6 |
| 7 #include "build/build_config.h" | 7 #include "build/build_config.h" |
| 8 | 8 |
| 9 #if defined(OS_WIN) | 9 #if defined(OS_WIN) |
| 10 #include <windows.h> | 10 #include <windows.h> |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 | 25 |
| 26 #include <iomanip> | 26 #include <iomanip> |
| 27 #include <list> | 27 #include <list> |
| 28 #include <string> | 28 #include <string> |
| 29 #include <vector> | 29 #include <vector> |
| 30 | 30 |
| 31 #include "base/basictypes.h" | 31 #include "base/basictypes.h" |
| 32 #include "base/lock.h" | 32 #include "base/lock.h" |
| 33 #include "base/platform_thread.h" | 33 #include "base/platform_thread.h" |
| 34 #include "base/scoped_ptr.h" | 34 #include "base/scoped_ptr.h" |
| 35 #include "base/sha1.h" |
| 35 #include "base/string_util.h" | 36 #include "base/string_util.h" |
| 36 #include "base/task.h" | 37 #include "base/task.h" |
| 37 #include "base/utf_string_conversions.h" | 38 #include "base/utf_string_conversions.h" |
| 38 #include "chrome/browser/sync/engine/all_status.h" | 39 #include "chrome/browser/sync/engine/all_status.h" |
| 39 #include "chrome/browser/sync/engine/auth_watcher.h" | 40 #include "chrome/browser/sync/engine/auth_watcher.h" |
| 40 #include "chrome/browser/sync/engine/change_reorder_buffer.h" | 41 #include "chrome/browser/sync/engine/change_reorder_buffer.h" |
| 41 #include "chrome/browser/sync/engine/model_safe_worker.h" | 42 #include "chrome/browser/sync/engine/model_safe_worker.h" |
| 42 #include "chrome/browser/sync/engine/net/gaia_authenticator.h" | 43 #include "chrome/browser/sync/engine/net/gaia_authenticator.h" |
| 43 #include "chrome/browser/sync/engine/net/server_connection_manager.h" | 44 #include "chrome/browser/sync/engine/net/server_connection_manager.h" |
| 44 #include "chrome/browser/sync/engine/net/syncapi_server_connection_manager.h" | 45 #include "chrome/browser/sync/engine/net/syncapi_server_connection_manager.h" |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 } | 383 } |
| 383 } | 384 } |
| 384 | 385 |
| 385 //////////////////////////////////// | 386 //////////////////////////////////// |
| 386 // BaseNode member definitions. | 387 // BaseNode member definitions. |
| 387 | 388 |
| 388 BaseNode::BaseNode() {} | 389 BaseNode::BaseNode() {} |
| 389 | 390 |
| 390 BaseNode::~BaseNode() {} | 391 BaseNode::~BaseNode() {} |
| 391 | 392 |
| 393 std::string BaseNode::GenerateSyncableHash( |
| 394 syncable::ModelType model_type, const std::string& client_tag) { |
| 395 // blank PB with just the extension in it has termination symbol, |
| 396 // handy for delimiter |
| 397 sync_pb::EntitySpecifics serialized_type; |
| 398 syncable::AddDefaultExtensionValue(model_type, &serialized_type); |
| 399 std::string hash_input; |
| 400 serialized_type.AppendToString(&hash_input); |
| 401 hash_input.append(client_tag); |
| 402 return base::SHA1HashString(hash_input); |
| 403 } |
| 404 |
| 392 int64 BaseNode::GetParentId() const { | 405 int64 BaseNode::GetParentId() const { |
| 393 return IdToMetahandle(GetTransaction()->GetWrappedTrans(), | 406 return IdToMetahandle(GetTransaction()->GetWrappedTrans(), |
| 394 GetEntry()->Get(syncable::PARENT_ID)); | 407 GetEntry()->Get(syncable::PARENT_ID)); |
| 395 } | 408 } |
| 396 | 409 |
| 397 int64 BaseNode::GetId() const { | 410 int64 BaseNode::GetId() const { |
| 398 return GetEntry()->Get(syncable::META_HANDLE); | 411 return GetEntry()->Get(syncable::META_HANDLE); |
| 399 } | 412 } |
| 400 | 413 |
| 401 bool BaseNode::GetIsFolder() const { | 414 bool BaseNode::GetIsFolder() const { |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 549 DCHECK(!entry_) << "Init called twice"; | 562 DCHECK(!entry_) << "Init called twice"; |
| 550 DCHECK_NE(id, kInvalidId); | 563 DCHECK_NE(id, kInvalidId); |
| 551 entry_ = new syncable::MutableEntry(transaction_->GetWrappedWriteTrans(), | 564 entry_ = new syncable::MutableEntry(transaction_->GetWrappedWriteTrans(), |
| 552 syncable::GET_BY_HANDLE, id); | 565 syncable::GET_BY_HANDLE, id); |
| 553 return (entry_->good() && !entry_->Get(syncable::IS_DEL)); | 566 return (entry_->good() && !entry_->Get(syncable::IS_DEL)); |
| 554 } | 567 } |
| 555 | 568 |
| 556 // Find a node by client tag, and bind this WriteNode to it. | 569 // Find a node by client tag, and bind this WriteNode to it. |
| 557 // Return true if the write node was found, and was not deleted. | 570 // Return true if the write node was found, and was not deleted. |
| 558 // Undeleting a deleted node is possible by ClientTag. | 571 // Undeleting a deleted node is possible by ClientTag. |
| 559 bool WriteNode::InitByClientTagLookup(const std::string& tag) { | 572 bool WriteNode::InitByClientTagLookup(syncable::ModelType model_type, |
| 573 const std::string& tag) { |
| 560 DCHECK(!entry_) << "Init called twice"; | 574 DCHECK(!entry_) << "Init called twice"; |
| 561 if (tag.empty()) | 575 if (tag.empty()) |
| 562 return false; | 576 return false; |
| 577 |
| 578 const std::string hash = GenerateSyncableHash(model_type, tag); |
| 579 |
| 563 entry_ = new syncable::MutableEntry(transaction_->GetWrappedWriteTrans(), | 580 entry_ = new syncable::MutableEntry(transaction_->GetWrappedWriteTrans(), |
| 564 syncable::GET_BY_CLIENT_TAG, tag); | 581 syncable::GET_BY_CLIENT_TAG, hash); |
| 565 return (entry_->good() && !entry_->Get(syncable::IS_DEL)); | 582 return (entry_->good() && !entry_->Get(syncable::IS_DEL)); |
| 566 } | 583 } |
| 567 | 584 |
| 568 void WriteNode::PutModelType(syncable::ModelType model_type) { | 585 void WriteNode::PutModelType(syncable::ModelType model_type) { |
| 569 // Set an empty specifics of the appropriate datatype. The presence | 586 // Set an empty specifics of the appropriate datatype. The presence |
| 570 // of the specific extension will identify the model type. | 587 // of the specific extension will identify the model type. |
| 588 DCHECK(GetModelType() == model_type || |
| 589 GetModelType() == syncable::UNSPECIFIED); // Immutable once set. |
| 590 |
| 571 sync_pb::EntitySpecifics specifics; | 591 sync_pb::EntitySpecifics specifics; |
| 572 syncable::AddDefaultExtensionValue(model_type, &specifics); | 592 syncable::AddDefaultExtensionValue(model_type, &specifics); |
| 573 PutSpecificsAndMarkForSyncing(specifics); | 593 PutSpecificsAndMarkForSyncing(specifics); |
| 574 DCHECK(GetModelType() == model_type); | 594 DCHECK(GetModelType() == model_type); |
| 575 } | 595 } |
| 576 | 596 |
| 577 // Create a new node with default properties, and bind this WriteNode to it. | 597 // Create a new node with default properties, and bind this WriteNode to it. |
| 578 // Return true on success. | 598 // Return true on success. |
| 579 bool WriteNode::InitByCreation(syncable::ModelType model_type, | 599 bool WriteNode::InitByCreation(syncable::ModelType model_type, |
| 580 const BaseNode& parent, | 600 const BaseNode& parent, |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 613 // and bind this WriteNode to it. | 633 // and bind this WriteNode to it. |
| 614 // Return true on success. If the tag exists in the database, then | 634 // Return true on success. If the tag exists in the database, then |
| 615 // we will attempt to undelete the node. | 635 // we will attempt to undelete the node. |
| 616 // TODO(chron): Code datatype into hash tag. | 636 // TODO(chron): Code datatype into hash tag. |
| 617 // TODO(chron): Is model type ever lost? | 637 // TODO(chron): Is model type ever lost? |
| 618 bool WriteNode::InitUniqueByCreation(syncable::ModelType model_type, | 638 bool WriteNode::InitUniqueByCreation(syncable::ModelType model_type, |
| 619 const BaseNode& parent, | 639 const BaseNode& parent, |
| 620 const std::string& tag) { | 640 const std::string& tag) { |
| 621 DCHECK(!entry_) << "Init called twice"; | 641 DCHECK(!entry_) << "Init called twice"; |
| 622 | 642 |
| 643 const std::string hash = GenerateSyncableHash(model_type, tag); |
| 644 |
| 623 syncable::Id parent_id = parent.GetEntry()->Get(syncable::ID); | 645 syncable::Id parent_id = parent.GetEntry()->Get(syncable::ID); |
| 624 | 646 |
| 625 // Start out with a dummy name. We expect | 647 // Start out with a dummy name. We expect |
| 626 // the caller to set a meaningful name after creation. | 648 // the caller to set a meaningful name after creation. |
| 627 string dummy(kDefaultNameForNewNodes); | 649 string dummy(kDefaultNameForNewNodes); |
| 628 | 650 |
| 629 // Check if we have this locally and need to undelete it. | 651 // Check if we have this locally and need to undelete it. |
| 630 scoped_ptr<syncable::MutableEntry> existing_entry( | 652 scoped_ptr<syncable::MutableEntry> existing_entry( |
| 631 new syncable::MutableEntry(transaction_->GetWrappedWriteTrans(), | 653 new syncable::MutableEntry(transaction_->GetWrappedWriteTrans(), |
| 632 syncable::GET_BY_CLIENT_TAG, tag)); | 654 syncable::GET_BY_CLIENT_TAG, hash)); |
| 633 | 655 |
| 634 if (existing_entry->good()) { | 656 if (existing_entry->good()) { |
| 635 if (existing_entry->Get(syncable::IS_DEL)) { | 657 if (existing_entry->Get(syncable::IS_DEL)) { |
| 636 // Rules for undelete: | 658 // Rules for undelete: |
| 637 // BASE_VERSION: Must keep the same. | 659 // BASE_VERSION: Must keep the same. |
| 638 // ID: Essential to keep the same. | 660 // ID: Essential to keep the same. |
| 639 // META_HANDLE: Must be the same, so we can't "split" the entry. | 661 // META_HANDLE: Must be the same, so we can't "split" the entry. |
| 640 // IS_DEL: Must be set to false, will cause reindexing. | 662 // IS_DEL: Must be set to false, will cause reindexing. |
| 641 // This one is weird because IS_DEL is true for "update only" | 663 // This one is weird because IS_DEL is true for "update only" |
| 642 // items. It should be OK to undelete an update only. | 664 // items. It should be OK to undelete an update only. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 663 return false; | 685 return false; |
| 664 } | 686 } |
| 665 } else { | 687 } else { |
| 666 entry_ = new syncable::MutableEntry(transaction_->GetWrappedWriteTrans(), | 688 entry_ = new syncable::MutableEntry(transaction_->GetWrappedWriteTrans(), |
| 667 syncable::CREATE, parent_id, dummy); | 689 syncable::CREATE, parent_id, dummy); |
| 668 if (!entry_->good()) { | 690 if (!entry_->good()) { |
| 669 return false; | 691 return false; |
| 670 } | 692 } |
| 671 | 693 |
| 672 // Only set IS_DIR for new entries. Don't bitflip undeleted ones. | 694 // Only set IS_DIR for new entries. Don't bitflip undeleted ones. |
| 673 entry_->Put(syncable::UNIQUE_CLIENT_TAG, tag); | 695 entry_->Put(syncable::UNIQUE_CLIENT_TAG, hash); |
| 674 } | 696 } |
| 675 | 697 |
| 676 // We don't support directory and tag combinations. | 698 // We don't support directory and tag combinations. |
| 677 entry_->Put(syncable::IS_DIR, false); | 699 entry_->Put(syncable::IS_DIR, false); |
| 678 | 700 |
| 679 // Will clear specifics data. | 701 // Will clear specifics data. |
| 680 PutModelType(model_type); | 702 PutModelType(model_type); |
| 681 | 703 |
| 682 // Now set the predecessor, which sets IS_UNSYNCED as necessary. | 704 // Now set the predecessor, which sets IS_UNSYNCED as necessary. |
| 683 PutPredecessor(NULL); | 705 PutPredecessor(NULL); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 774 return false; | 796 return false; |
| 775 if (entry_->Get(syncable::IS_DEL)) | 797 if (entry_->Get(syncable::IS_DEL)) |
| 776 return false; | 798 return false; |
| 777 syncable::ModelType model_type = GetModelType(); | 799 syncable::ModelType model_type = GetModelType(); |
| 778 LOG_IF(WARNING, model_type == syncable::UNSPECIFIED || | 800 LOG_IF(WARNING, model_type == syncable::UNSPECIFIED || |
| 779 model_type == syncable::TOP_LEVEL_FOLDER) | 801 model_type == syncable::TOP_LEVEL_FOLDER) |
| 780 << "SyncAPI InitByIdLookup referencing unusual object."; | 802 << "SyncAPI InitByIdLookup referencing unusual object."; |
| 781 return true; | 803 return true; |
| 782 } | 804 } |
| 783 | 805 |
| 784 bool ReadNode::InitByClientTagLookup(const std::string& tag) { | 806 bool ReadNode::InitByClientTagLookup(syncable::ModelType model_type, |
| 807 const std::string& tag) { |
| 785 DCHECK(!entry_) << "Init called twice"; | 808 DCHECK(!entry_) << "Init called twice"; |
| 786 if (tag.empty()) | 809 if (tag.empty()) |
| 787 return false; | 810 return false; |
| 811 |
| 812 const std::string hash = GenerateSyncableHash(model_type, tag); |
| 813 |
| 788 entry_ = new syncable::Entry(transaction_->GetWrappedTrans(), | 814 entry_ = new syncable::Entry(transaction_->GetWrappedTrans(), |
| 789 syncable::GET_BY_CLIENT_TAG, tag); | 815 syncable::GET_BY_CLIENT_TAG, hash); |
| 790 return (entry_->good() && !entry_->Get(syncable::IS_DEL)); | 816 return (entry_->good() && !entry_->Get(syncable::IS_DEL)); |
| 791 } | 817 } |
| 792 | 818 |
| 793 const syncable::Entry* ReadNode::GetEntry() const { | 819 const syncable::Entry* ReadNode::GetEntry() const { |
| 794 return entry_; | 820 return entry_; |
| 795 } | 821 } |
| 796 | 822 |
| 797 const BaseTransaction* ReadNode::GetTransaction() const { | 823 const BaseTransaction* ReadNode::GetTransaction() const { |
| 798 return transaction_; | 824 return transaction_; |
| 799 } | 825 } |
| (...skipping 1038 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1838 BaseTransaction::~BaseTransaction() { | 1864 BaseTransaction::~BaseTransaction() { |
| 1839 delete lookup_; | 1865 delete lookup_; |
| 1840 } | 1866 } |
| 1841 | 1867 |
| 1842 UserShare* SyncManager::GetUserShare() const { | 1868 UserShare* SyncManager::GetUserShare() const { |
| 1843 DCHECK(data_->initialized()) << "GetUserShare requires initialization!"; | 1869 DCHECK(data_->initialized()) << "GetUserShare requires initialization!"; |
| 1844 return data_->GetUserShare(); | 1870 return data_->GetUserShare(); |
| 1845 } | 1871 } |
| 1846 | 1872 |
| 1847 } // namespace sync_api | 1873 } // namespace sync_api |
| OLD | NEW |