Chromium Code Reviews| 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/sync_manager_impl.h" | 5 #include "sync/internal_api/sync_manager_impl.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/base64.h" | 9 #include "base/base64.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 492 trans.GetCryptographer()->BootstrapKeystoreKey( | 492 trans.GetCryptographer()->BootstrapKeystoreKey( |
| 493 restored_keystore_key_for_bootstrapping); | 493 restored_keystore_key_for_bootstrapping); |
| 494 trans.GetCryptographer()->AddObserver(this); | 494 trans.GetCryptographer()->AddObserver(this); |
| 495 | 495 |
| 496 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, | 496 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, |
| 497 OnInitializationComplete( | 497 OnInitializationComplete( |
| 498 MakeWeakHandle(weak_ptr_factory_.GetWeakPtr()), | 498 MakeWeakHandle(weak_ptr_factory_.GetWeakPtr()), |
| 499 true, InitialSyncEndedTypes())); | 499 true, InitialSyncEndedTypes())); |
| 500 } | 500 } |
| 501 | 501 |
| 502 void SyncManagerImpl::RefreshNigori(const std::string& chrome_version, | 502 void SyncManagerImpl::InitialProcessMetadata( |
| 503 const base::Closure& done_callback) { | 503 const std::string& chrome_version, |
| 504 const base::Closure& done_callback) { | |
| 504 DCHECK(initialized_); | 505 DCHECK(initialized_); |
| 505 DCHECK(thread_checker_.CalledOnValidThread()); | 506 DCHECK(thread_checker_.CalledOnValidThread()); |
| 506 GetSessionName( | 507 GetSessionName(blocking_task_runner_, |
| 507 blocking_task_runner_, | 508 base::Bind( |
| 508 base::Bind( | 509 &SyncManagerImpl::InitialProcessMetadataContinuation, |
| 509 &SyncManagerImpl::UpdateCryptographerAndNigoriCallback, | 510 weak_ptr_factory_.GetWeakPtr(), |
| 510 weak_ptr_factory_.GetWeakPtr(), | 511 chrome_version, |
| 511 chrome_version, | 512 done_callback)); |
| 512 done_callback)); | 513 } |
| 514 | |
| 515 void SyncManagerImpl::InitialProcessMetadataContinuation( | |
|
rlarocque
2012/08/11 01:31:52
This would be a great place to put the code that c
| |
| 516 const std::string& chrome_version, | |
| 517 const base::Closure& done_callback, | |
| 518 const std::string& session_name) { | |
| 519 UpdateCryptographerAndNigori(); | |
| 520 UpdateDeviceInformation(chrome_version, session_name); | |
| 521 done_callback.Run(); | |
| 513 } | 522 } |
| 514 | 523 |
| 515 void SyncManagerImpl::UpdateNigoriEncryptionState( | 524 void SyncManagerImpl::UpdateNigoriEncryptionState( |
| 516 Cryptographer* cryptographer, | 525 Cryptographer* cryptographer, |
| 517 WriteNode* nigori_node) { | 526 WriteNode* nigori_node) { |
| 518 DCHECK(nigori_node); | 527 DCHECK(nigori_node); |
| 519 sync_pb::NigoriSpecifics nigori = nigori_node->GetNigoriSpecifics(); | 528 sync_pb::NigoriSpecifics nigori = nigori_node->GetNigoriSpecifics(); |
| 520 | 529 |
| 521 if (cryptographer->is_ready() && | 530 if (cryptographer->is_ready() && |
| 522 nigori_overwrite_count_ < kNigoriOverwriteLimit) { | 531 nigori_overwrite_count_ < kNigoriOverwriteLimit) { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 539 // Note: we don't try to set using_explicit_passphrase here since if that | 548 // Note: we don't try to set using_explicit_passphrase here since if that |
| 540 // is lost the user can always set it again. The main point is to preserve | 549 // is lost the user can always set it again. The main point is to preserve |
| 541 // the encryption keys so all data remains decryptable. | 550 // the encryption keys so all data remains decryptable. |
| 542 } | 551 } |
| 543 cryptographer->UpdateNigoriFromEncryptedTypes(&nigori); | 552 cryptographer->UpdateNigoriFromEncryptedTypes(&nigori); |
| 544 | 553 |
| 545 // If nothing has changed, this is a no-op. | 554 // If nothing has changed, this is a no-op. |
| 546 nigori_node->SetNigoriSpecifics(nigori); | 555 nigori_node->SetNigoriSpecifics(nigori); |
| 547 } | 556 } |
| 548 | 557 |
| 549 void SyncManagerImpl::UpdateCryptographerAndNigoriCallback( | 558 void SyncManagerImpl::UpdateCryptographerAndNigori() { |
| 550 const std::string& chrome_version, | 559 DCHECK(directory()->initial_sync_ended_for_type(NIGORI)); |
| 551 const base::Closure& done_callback, | |
| 552 const std::string& session_name) { | |
| 553 if (!directory()->initial_sync_ended_for_type(NIGORI)) { | |
| 554 done_callback.Run(); // Should only happen during first time sync. | |
| 555 return; | |
| 556 } | |
| 557 | 560 |
| 558 bool success = false; | 561 bool success = false; |
| 559 { | 562 { |
| 560 WriteTransaction trans(FROM_HERE, GetUserShare()); | 563 WriteTransaction trans(FROM_HERE, GetUserShare()); |
| 561 Cryptographer* cryptographer = trans.GetCryptographer(); | 564 Cryptographer* cryptographer = trans.GetCryptographer(); |
| 562 WriteNode node(&trans); | 565 WriteNode node(&trans); |
| 563 | 566 |
| 564 if (node.InitByTagLookup(kNigoriTag) == BaseNode::INIT_OK) { | 567 if (node.InitByTagLookup(kNigoriTag) == BaseNode::INIT_OK) { |
| 565 sync_pb::NigoriSpecifics nigori(node.GetNigoriSpecifics()); | 568 sync_pb::NigoriSpecifics nigori(node.GetNigoriSpecifics()); |
| 566 Cryptographer::UpdateResult result = cryptographer->Update(nigori); | 569 Cryptographer::UpdateResult result = cryptographer->Update(nigori); |
| 567 if (result == Cryptographer::NEEDS_PASSPHRASE) { | 570 if (result == Cryptographer::NEEDS_PASSPHRASE) { |
| 568 sync_pb::EncryptedData pending_keys; | 571 sync_pb::EncryptedData pending_keys; |
| 569 if (cryptographer->has_pending_keys()) | 572 if (cryptographer->has_pending_keys()) |
| 570 pending_keys = cryptographer->GetPendingKeys(); | 573 pending_keys = cryptographer->GetPendingKeys(); |
| 571 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, | 574 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, |
| 572 OnPassphraseRequired(REASON_DECRYPTION, | 575 OnPassphraseRequired(REASON_DECRYPTION, |
| 573 pending_keys)); | 576 pending_keys)); |
| 574 } | 577 } |
| 575 | 578 |
| 576 // Add or update device information. | |
| 577 bool contains_this_device = false; | |
| 578 for (int i = 0; i < nigori.device_information_size(); ++i) { | |
| 579 const sync_pb::DeviceInformation& device_information = | |
| 580 nigori.device_information(i); | |
| 581 if (device_information.cache_guid() == directory()->cache_guid()) { | |
| 582 // Update the version number in case it changed due to an update. | |
| 583 if (device_information.chrome_version() != chrome_version) { | |
| 584 sync_pb::DeviceInformation* mutable_device_information = | |
| 585 nigori.mutable_device_information(i); | |
| 586 mutable_device_information->set_chrome_version( | |
| 587 chrome_version); | |
| 588 } | |
| 589 contains_this_device = true; | |
| 590 } | |
| 591 } | |
| 592 | |
| 593 if (!contains_this_device) { | |
| 594 sync_pb::DeviceInformation* device_information = | |
| 595 nigori.add_device_information(); | |
| 596 device_information->set_cache_guid(directory()->cache_guid()); | |
| 597 #if defined(OS_CHROMEOS) | |
| 598 device_information->set_platform("ChromeOS"); | |
| 599 #elif defined(OS_LINUX) | |
| 600 device_information->set_platform("Linux"); | |
| 601 #elif defined(OS_MACOSX) | |
| 602 device_information->set_platform("Mac"); | |
| 603 #elif defined(OS_WIN) | |
| 604 device_information->set_platform("Windows"); | |
| 605 #endif | |
| 606 device_information->set_name(session_name); | |
| 607 device_information->set_chrome_version(chrome_version); | |
| 608 } | |
| 609 // Disabled to avoid nigori races. TODO(zea): re-enable. crbug.com/122837 | |
| 610 // node.SetNigoriSpecifics(nigori); | |
| 611 | 579 |
| 612 // Make sure the nigori node has the up to date encryption info. | 580 // Make sure the nigori node has the up to date encryption info. |
| 613 UpdateNigoriEncryptionState(cryptographer, &node); | 581 UpdateNigoriEncryptionState(cryptographer, &node); |
| 614 | 582 |
| 615 NotifyCryptographerState(cryptographer); | 583 NotifyCryptographerState(cryptographer); |
| 616 allstatus_.SetEncryptedTypes(cryptographer->GetEncryptedTypes()); | 584 allstatus_.SetEncryptedTypes(cryptographer->GetEncryptedTypes()); |
| 617 | 585 |
| 618 success = cryptographer->is_ready(); | 586 success = cryptographer->is_ready(); |
| 619 } else { | 587 } else { |
| 620 NOTREACHED(); | 588 NOTREACHED(); |
| 621 } | 589 } |
| 622 } | 590 } |
| 623 | 591 |
| 624 if (success) | 592 if (success) |
| 625 RefreshEncryption(); | 593 RefreshEncryption(); |
| 626 done_callback.Run(); | 594 } |
| 595 | |
| 596 void SyncManagerImpl::UpdateDeviceInformation(const std::string& chrome_version, | |
| 597 const std::string& session_name) { | |
| 598 DCHECK(!directory()->cache_guid().empty()); | |
| 599 | |
| 600 WriteTransaction trans(FROM_HERE, GetUserShare()); | |
| 601 | |
| 602 WriteNode node(&trans); | |
| 603 BaseNode::InitByLookupResult lookup_result = | |
| 604 node.InitByClientTagLookup(PER_DEVICE_METADATA, | |
| 605 directory()->cache_guid()); | |
| 606 if (lookup_result == BaseNode::INIT_OK) { | |
| 607 // Found an existing node. Update its version, if necessary. | |
| 608 sync_pb::PerDeviceSpecifics specifics = node.GetPerDeviceSpecifics(); | |
| 609 if (specifics.device_information().chrome_version() != chrome_version) { | |
| 610 specifics.mutable_device_information()->set_chrome_version( | |
| 611 chrome_version); | |
| 612 node.SetPerDeviceSpecifics(specifics); | |
| 613 } | |
| 614 } else { | |
| 615 ReadNode type_root(&trans); | |
| 616 BaseNode::InitByLookupResult type_root_lookup_result = | |
| 617 type_root.InitByTagLookup(ModelTypeToRootTag(PER_DEVICE_METADATA)); | |
| 618 DCHECK(type_root_lookup_result == BaseNode::INIT_OK); | |
| 619 | |
| 620 WriteNode new_node(&trans); | |
| 621 WriteNode::InitUniqueByCreationResult create_result = | |
| 622 new_node.InitUniqueByCreation(PER_DEVICE_METADATA, | |
| 623 type_root, | |
| 624 directory()->cache_guid()); | |
| 625 DCHECK(create_result == WriteNode::INIT_SUCCESS); | |
| 626 sync_pb::PerDeviceSpecifics per_device_specifics = | |
| 627 new_node.GetPerDeviceSpecifics(); | |
| 628 sync_pb::DeviceInformation* device_information = | |
| 629 per_device_specifics.mutable_device_information(); | |
| 630 | |
| 631 device_information->set_cache_guid(directory()->cache_guid()); | |
| 632 device_information->set_name(session_name); | |
| 633 device_information->set_chrome_version(chrome_version); | |
| 634 | |
| 635 #if defined(OS_CHROMEOS) | |
| 636 device_information->set_platform("ChromeOS"); | |
| 637 #elif defined(OS_LINUX) | |
| 638 device_information->set_platform("Linux"); | |
| 639 #elif defined(OS_MACOSX) | |
| 640 device_information->set_platform("Mac"); | |
| 641 #elif defined(OS_WIN) | |
| 642 device_information->set_platform("Windows"); | |
| 643 #endif | |
| 644 new_node.SetPerDeviceSpecifics(per_device_specifics); | |
| 645 } | |
| 627 } | 646 } |
| 628 | 647 |
| 629 void SyncManagerImpl::NotifyCryptographerState(Cryptographer * cryptographer) { | 648 void SyncManagerImpl::NotifyCryptographerState(Cryptographer * cryptographer) { |
| 630 // TODO(lipalani): Explore the possibility of hooking this up to | 649 // TODO(lipalani): Explore the possibility of hooking this up to |
| 631 // SyncManager::Observer and making |AllStatus| a listener for that. | 650 // SyncManager::Observer and making |AllStatus| a listener for that. |
| 632 allstatus_.SetCryptographerReady(cryptographer->is_ready()); | 651 allstatus_.SetCryptographerReady(cryptographer->is_ready()); |
| 633 allstatus_.SetCryptoHasPendingKeys(cryptographer->has_pending_keys()); | 652 allstatus_.SetCryptoHasPendingKeys(cryptographer->has_pending_keys()); |
| 634 debug_info_event_listener_.SetCryptographerReady(cryptographer->is_ready()); | 653 debug_info_event_listener_.SetCryptographerReady(cryptographer->is_ready()); |
| 635 debug_info_event_listener_.SetCrytographerHasPendingKeys( | 654 debug_info_event_listener_.SetCrytographerHasPendingKeys( |
| 636 cryptographer->has_pending_keys()); | 655 cryptographer->has_pending_keys()); |
| (...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1136 // the lookup of the root node will fail and we will skip encryption for that | 1155 // the lookup of the root node will fail and we will skip encryption for that |
| 1137 // type. | 1156 // type. |
| 1138 void SyncManagerImpl::ReEncryptEverything( | 1157 void SyncManagerImpl::ReEncryptEverything( |
| 1139 WriteTransaction* trans) { | 1158 WriteTransaction* trans) { |
| 1140 Cryptographer* cryptographer = trans->GetCryptographer(); | 1159 Cryptographer* cryptographer = trans->GetCryptographer(); |
| 1141 if (!cryptographer || !cryptographer->is_ready()) | 1160 if (!cryptographer || !cryptographer->is_ready()) |
| 1142 return; | 1161 return; |
| 1143 ModelTypeSet encrypted_types = GetEncryptedTypes(trans); | 1162 ModelTypeSet encrypted_types = GetEncryptedTypes(trans); |
| 1144 for (ModelTypeSet::Iterator iter = encrypted_types.First(); | 1163 for (ModelTypeSet::Iterator iter = encrypted_types.First(); |
| 1145 iter.Good(); iter.Inc()) { | 1164 iter.Good(); iter.Inc()) { |
| 1146 if (iter.Get() == PASSWORDS || iter.Get() == NIGORI) | 1165 if (iter.Get() == PASSWORDS || IsControlType(iter.Get())) |
| 1147 continue; // These types handle encryption differently. | 1166 continue; // These types handle encryption differently. |
| 1148 | 1167 |
| 1149 ReadNode type_root(trans); | 1168 ReadNode type_root(trans); |
| 1150 std::string tag = ModelTypeToRootTag(iter.Get()); | 1169 std::string tag = ModelTypeToRootTag(iter.Get()); |
| 1151 if (type_root.InitByTagLookup(tag) != BaseNode::INIT_OK) | 1170 if (type_root.InitByTagLookup(tag) != BaseNode::INIT_OK) |
| 1152 continue; // Don't try to reencrypt if the type's data is unavailable. | 1171 continue; // Don't try to reencrypt if the type's data is unavailable. |
| 1153 | 1172 |
| 1154 // Iterate through all children of this datatype. | 1173 // Iterate through all children of this datatype. |
| 1155 std::queue<int64> to_visit; | 1174 std::queue<int64> to_visit; |
| 1156 int64 child_id = type_root.GetFirstChildId(); | 1175 int64 child_id = type_root.GetFirstChildId(); |
| (...skipping 760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1917 int SyncManagerImpl::GetDefaultNudgeDelay() { | 1936 int SyncManagerImpl::GetDefaultNudgeDelay() { |
| 1918 return kDefaultNudgeDelayMilliseconds; | 1937 return kDefaultNudgeDelayMilliseconds; |
| 1919 } | 1938 } |
| 1920 | 1939 |
| 1921 // static. | 1940 // static. |
| 1922 int SyncManagerImpl::GetPreferencesNudgeDelay() { | 1941 int SyncManagerImpl::GetPreferencesNudgeDelay() { |
| 1923 return kPreferencesNudgeDelayMilliseconds; | 1942 return kPreferencesNudgeDelayMilliseconds; |
| 1924 } | 1943 } |
| 1925 | 1944 |
| 1926 } // namespace syncer | 1945 } // namespace syncer |
| OLD | NEW |