Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 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/glue/session_model_associator.h" | 5 #include "chrome/browser/sync/glue/session_model_associator.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/tracked.h" | 12 #include "base/tracked.h" |
| 13 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
| 14 #include "chrome/browser/sessions/session_service_factory.h" | 14 #include "chrome/browser/sessions/session_service_factory.h" |
| 15 #include "chrome/browser/sync/api/sync_error.h" | 15 #include "chrome/browser/sync/api/sync_error.h" |
| 16 #include "chrome/browser/sync/glue/synced_tab_delegate.h" | 16 #include "chrome/browser/sync/glue/synced_tab_delegate.h" |
| 17 #include "chrome/browser/sync/glue/synced_window_delegate.h" | 17 #include "chrome/browser/sync/glue/synced_window_delegate.h" |
| 18 #include "chrome/browser/sync/internal_api/read_node.h" | 18 #include "chrome/browser/sync/internal_api/read_node.h" |
| 19 #include "chrome/browser/sync/internal_api/read_transaction.h" | 19 #include "chrome/browser/sync/internal_api/read_transaction.h" |
| 20 #include "chrome/browser/sync/internal_api/write_node.h" | 20 #include "chrome/browser/sync/internal_api/write_node.h" |
| 21 #include "chrome/browser/sync/internal_api/write_transaction.h" | 21 #include "chrome/browser/sync/internal_api/write_transaction.h" |
| 22 #include "chrome/browser/sync/profile_sync_service.h" | 22 #include "chrome/browser/sync/profile_sync_service.h" |
| 23 #include "chrome/browser/sync/syncable/syncable.h" | 23 #include "chrome/browser/sync/syncable/syncable.h" |
| 24 #include "chrome/common/chrome_notification_types.h" | 24 #include "chrome/common/chrome_notification_types.h" |
| 25 #include "chrome/common/url_constants.h" | 25 #include "chrome/common/url_constants.h" |
| 26 #include "content/browser/tab_contents/navigation_entry.h" | 26 #include "content/browser/tab_contents/navigation_entry.h" |
| 27 #include "content/common/notification_details.h" | 27 #include "content/common/notification_details.h" |
| 28 #include "content/common/notification_service.h" | 28 #include "content/common/notification_service.h" |
| 29 #if defined(OS_LINUX) | |
| 30 #include "base/linux_util.h" | |
| 31 #elif defined(OS_MACOSX) | |
| 32 #include <sys/sysctl.h> // sysctlbyname() | |
| 33 #include "base/sys_info.h" | |
| 34 #include "base/string_util.h" | |
| 35 #elif defined(OS_WIN) | |
| 36 #include <windows.h> | |
| 37 #endif | |
| 29 | 38 |
| 30 namespace browser_sync { | 39 namespace browser_sync { |
| 31 | 40 |
| 32 namespace { | 41 namespace { |
| 33 static const char kNoSessionsFolderError[] = | 42 static const char kNoSessionsFolderError[] = |
| 34 "Server did not create the top-level sessions node. We " | 43 "Server did not create the top-level sessions node. We " |
| 35 "might be running against an out-of-date server."; | 44 "might be running against an out-of-date server."; |
| 36 | 45 |
| 37 // The maximum number of navigations in each direction we care to sync. | 46 // The maximum number of navigations in each direction we care to sync. |
| 38 static const int max_sync_navigation_count = 6; | 47 static const int max_sync_navigation_count = 6; |
| 39 } // namespace | 48 } // namespace |
| 40 | 49 |
| 50 std::string SessionModelAssociator::current_machine_name_ = ""; | |
|
Nicolas Zea
2011/08/30 21:29:58
You can remove this line (default value for a stri
Yaron
2011/08/31 03:26:12
But since it's static, I need to have a concrete i
Nicolas Zea
2011/08/31 18:23:00
Woops, I didn't read this properly. Yeah, this def
Yaron
2011/08/31 23:23:21
Done.
| |
| 51 | |
| 41 SessionModelAssociator::SessionModelAssociator(ProfileSyncService* sync_service) | 52 SessionModelAssociator::SessionModelAssociator(ProfileSyncService* sync_service) |
| 42 : tab_pool_(sync_service), | 53 : tab_pool_(sync_service), |
| 43 local_session_syncid_(sync_api::kInvalidId), | 54 local_session_syncid_(sync_api::kInvalidId), |
| 44 sync_service_(sync_service), | 55 sync_service_(sync_service), |
| 45 setup_for_test_(false), | 56 setup_for_test_(false), |
| 46 waiting_for_change_(false), | 57 waiting_for_change_(false), |
| 47 ALLOW_THIS_IN_INITIALIZER_LIST(test_method_factory_(this)) { | 58 ALLOW_THIS_IN_INITIALIZER_LIST(test_method_factory_(this)) { |
| 48 DCHECK(CalledOnValidThread()); | 59 DCHECK(CalledOnValidThread()); |
| 49 DCHECK(sync_service_); | 60 DCHECK(sync_service_); |
| 50 } | 61 } |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 116 } | 127 } |
| 117 | 128 |
| 118 void SessionModelAssociator::ReassociateWindows(bool reload_tabs) { | 129 void SessionModelAssociator::ReassociateWindows(bool reload_tabs) { |
| 119 DCHECK(CalledOnValidThread()); | 130 DCHECK(CalledOnValidThread()); |
| 120 std::string local_tag = GetCurrentMachineTag(); | 131 std::string local_tag = GetCurrentMachineTag(); |
| 121 sync_pb::SessionSpecifics specifics; | 132 sync_pb::SessionSpecifics specifics; |
| 122 specifics.set_session_tag(local_tag); | 133 specifics.set_session_tag(local_tag); |
| 123 sync_pb::SessionHeader* header_s = specifics.mutable_header(); | 134 sync_pb::SessionHeader* header_s = specifics.mutable_header(); |
| 124 SyncedSession* current_session = | 135 SyncedSession* current_session = |
| 125 synced_session_tracker_.GetSession(local_tag); | 136 synced_session_tracker_.GetSession(local_tag); |
| 137 header_s->set_client_name(current_machine_name_); | |
| 138 #if defined(OS_LINUX) | |
| 139 header_s->set_device_type(sync_pb::SessionHeader_DeviceType_TYPE_LINUX); | |
| 140 #elif defined(OS_MACOSX) | |
| 141 header_s->set_device_type(sync_pb::SessionHeader_DeviceType_TYPE_MAC); | |
| 142 #elif defined(OS_WIN) | |
| 143 header_s->set_device_type(sync_pb::SessionHeader_DeviceType_TYPE_WIN); | |
| 144 #elif defined(OS_CHROMEOS) | |
| 145 header_s->set_device_type(sync_pb::SessionHeader_DeviceType_TYPE_CROS); | |
| 146 #else | |
| 147 header_s->set_device_type(sync_pb::SessionHeader_DeviceType_TYPE_OTHER); | |
| 148 #endif | |
| 126 | 149 |
| 127 size_t window_num = 0; | 150 size_t window_num = 0; |
| 128 std::set<SyncedWindowDelegate*> windows = | 151 std::set<SyncedWindowDelegate*> windows = |
| 129 SyncedWindowDelegate::GetSyncedWindowDelegates(); | 152 SyncedWindowDelegate::GetSyncedWindowDelegates(); |
| 130 current_session->windows.reserve(windows.size()); | 153 current_session->windows.reserve(windows.size()); |
| 131 for (std::set<SyncedWindowDelegate*>::const_iterator i = | 154 for (std::set<SyncedWindowDelegate*>::const_iterator i = |
| 132 windows.begin(); i != windows.end(); ++i) { | 155 windows.begin(); i != windows.end(); ++i) { |
| 133 // Make sure the window has tabs and a viewable window. The viewable window | 156 // Make sure the window has tabs and a viewable window. The viewable window |
| 134 // check is necessary because, for example, when a browser is closed the | 157 // check is necessary because, for example, when a browser is closed the |
| 135 // destructor is not necessarily run immediately. This means its possible | 158 // destructor is not necessarily run immediately. This means its possible |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 420 { | 443 { |
| 421 sync_api::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare()); | 444 sync_api::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare()); |
| 422 | 445 |
| 423 sync_api::ReadNode root(&trans); | 446 sync_api::ReadNode root(&trans); |
| 424 if (!root.InitByTagLookup(kSessionsTag)) { | 447 if (!root.InitByTagLookup(kSessionsTag)) { |
| 425 error->Reset(FROM_HERE, kNoSessionsFolderError, model_type()); | 448 error->Reset(FROM_HERE, kNoSessionsFolderError, model_type()); |
| 426 return false; | 449 return false; |
| 427 } | 450 } |
| 428 | 451 |
| 429 // Make sure we have a machine tag. | 452 // Make sure we have a machine tag. |
| 430 if (current_machine_tag_.empty()) | 453 if (current_machine_tag_.empty()) { |
| 431 InitializeCurrentMachineTag(&trans); | 454 InitializeCurrentMachineTag(&trans); |
| 455 InitializeCurrentMachineName(); | |
| 456 } | |
| 432 synced_session_tracker_.SetLocalSessionTag(current_machine_tag_); | 457 synced_session_tracker_.SetLocalSessionTag(current_machine_tag_); |
| 433 if (!UpdateAssociationsFromSyncModel(root, &trans)) { | 458 if (!UpdateAssociationsFromSyncModel(root, &trans)) { |
| 434 error->Reset(FROM_HERE, | 459 error->Reset(FROM_HERE, |
| 435 "Failed to update associations from sync", | 460 "Failed to update associations from sync", |
| 436 model_type()); | 461 model_type()); |
| 437 return false; | 462 return false; |
| 438 } | 463 } |
| 439 | 464 |
| 440 if (local_session_syncid_ == sync_api::kInvalidId) { | 465 if (local_session_syncid_ == sync_api::kInvalidId) { |
| 441 // The sync db didn't have a header node for us, we need to create one. | 466 // The sync db didn't have a header node for us, we need to create one. |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 458 VLOG(1) << "Session models associated."; | 483 VLOG(1) << "Session models associated."; |
| 459 | 484 |
| 460 return true; | 485 return true; |
| 461 } | 486 } |
| 462 | 487 |
| 463 bool SessionModelAssociator::DisassociateModels(SyncError* error) { | 488 bool SessionModelAssociator::DisassociateModels(SyncError* error) { |
| 464 DCHECK(CalledOnValidThread()); | 489 DCHECK(CalledOnValidThread()); |
| 465 synced_session_tracker_.clear(); | 490 synced_session_tracker_.clear(); |
| 466 tab_map_.clear(); | 491 tab_map_.clear(); |
| 467 tab_pool_.clear(); | 492 tab_pool_.clear(); |
| 468 local_session_syncid_ = sync_api::kInvalidId; | 493 local_session_syncid_ = sync_api::kInvalidId; |
|
Nicolas Zea
2011/08/30 21:29:58
Should probably clear current_machine_name and cur
Yaron
2011/08/31 03:26:12
I cleared current_machine_tag_ but not current_mac
Nicolas Zea
2011/08/31 18:23:00
See above comment.
Yaron
2011/08/31 23:23:21
Done.
| |
| 469 | 494 |
| 470 // There is no local model stored with which to disassociate, just notify | 495 // There is no local model stored with which to disassociate, just notify |
| 471 // foreign session handlers. | 496 // foreign session handlers. |
| 472 NotificationService::current()->Notify( | 497 NotificationService::current()->Notify( |
| 473 chrome::NOTIFICATION_FOREIGN_SESSION_DISABLED, | 498 chrome::NOTIFICATION_FOREIGN_SESSION_DISABLED, |
| 474 NotificationService::AllSources(), | 499 NotificationService::AllSources(), |
| 475 NotificationService::NoDetails()); | 500 NotificationService::NoDetails()); |
| 476 return true; | 501 return true; |
| 477 } | 502 } |
| 478 | 503 |
| 479 void SessionModelAssociator::InitializeCurrentMachineTag( | 504 void SessionModelAssociator::InitializeCurrentMachineTag( |
| 480 sync_api::WriteTransaction* trans) { | 505 sync_api::WriteTransaction* trans) { |
| 481 DCHECK(CalledOnValidThread()); | 506 DCHECK(CalledOnValidThread()); |
| 482 syncable::Directory* dir = trans->GetWrappedWriteTrans()->directory(); | 507 syncable::Directory* dir = trans->GetWrappedWriteTrans()->directory(); |
| 483 | 508 |
| 484 // TODO(zea): We need a better way of creating a machine tag. The directory | 509 // TODO(zea): We need a better way of creating a machine tag. The directory |
|
Nicolas Zea
2011/08/30 21:29:58
This TODO no longer applies.
Yaron
2011/08/31 03:26:12
Well not entirely. The last bit of being human-rea
Nicolas Zea
2011/08/31 18:23:00
Tim and I have chatted about this before and we're
Yaron
2011/08/31 23:23:21
Done.
| |
| 485 // kernel's cache_guid changes every time syncing is turned on and off. This | 510 // kernel's cache_guid changes every time syncing is turned on and off. This |
| 486 // will result in session's associated with stale machine tags persisting on | 511 // will result in session's associated with stale machine tags persisting on |
| 487 // the server since that tag will not be reused. Eventually this should | 512 // the server since that tag will not be reused. Eventually this should |
| 488 // become some string identifiable to the user. (Home, Work, Laptop, etc.) | 513 // become some string identifiable to the user. (Home, Work, Laptop, etc.) |
| 489 // See issue at http://crbug.com/59672 | 514 // See issue at http://crbug.com/59672 |
| 490 current_machine_tag_ = "session_sync"; | 515 current_machine_tag_ = "session_sync"; |
| 491 current_machine_tag_.append(dir->cache_guid()); | 516 current_machine_tag_.append(dir->cache_guid()); |
| 492 VLOG(1) << "Creating machine tag: " << current_machine_tag_; | 517 VLOG(1) << "Creating machine tag: " << current_machine_tag_; |
| 493 tab_pool_.set_machine_tag(current_machine_tag_); | 518 tab_pool_.set_machine_tag(current_machine_tag_); |
| 494 } | 519 } |
| 495 | 520 |
| 521 // Static | |
| 522 void SessionModelAssociator::InitializeCurrentMachineName() { | |
| 523 #if defined(OS_LINUX) | |
| 524 current_machine_name_ = base::GetLinuxDistro(); | |
|
Nicolas Zea
2011/08/30 21:29:58
should probably check for the "Unknown" case and r
Yaron
2011/08/31 03:26:12
Done
| |
| 525 #elif defined(OS_MACOSX) | |
| 526 char modelBuffer[256]; | |
| 527 size_t length = sizeof(modelBuffer); | |
| 528 if (!sysctlbyname("hw.model", modelBuffer, &length, NULL, 0)) { | |
|
Nicolas Zea
2011/08/30 21:29:58
I'm not familiar with these API's, so my main conc
Yaron
2011/08/31 03:26:12
Split off GetComputerName to win_util and GetHardw
| |
| 529 for (size_t i = 0; i < length; i++) { | |
| 530 if (IsAsciiDigit(modelBuffer[i])) { | |
| 531 current_machine_name_ = std::string(modelBuffer, 0, i); | |
| 532 return; | |
| 533 } | |
| 534 } | |
| 535 // If we didn't find a number in the string, Just use Mac OS X. | |
|
Nicolas Zea
2011/08/30 21:29:58
Why not just use the full string?
Yaron
2011/08/31 03:26:12
Hmm. I suppose that could be better
| |
| 536 current_machine_name_ = base::SysInfo::OperatingSystemName(); | |
| 537 } else { | |
| 538 // Can't read hardware model. Just use Mac OS X. | |
| 539 current_machine_name_ = base::SysInfo::OperatingSystemName(); | |
| 540 } | |
| 541 #elif defined(OS_WIN) | |
| 542 char computer_name[MAX_COMPUTERNAME_LENGTH + 1]; | |
| 543 DWORD size = sizeof(computer_name); | |
| 544 if (GetComputerNameA(computer_name, &size)) { | |
| 545 current_machine_name_ = computer_name; | |
| 546 } else { | |
| 547 current_machine_name_ = "Windows"; | |
| 548 } | |
| 549 #elif defined(OS_CHROMEOS) | |
| 550 current_machine_name_ = "Chromebook"; | |
| 551 #endif | |
|
Nicolas Zea
2011/08/30 21:29:58
else "Unknown OS"
Yaron
2011/08/31 03:26:12
I added a catch-all case instead (because it also
| |
| 552 } | |
| 553 | |
| 554 | |
| 496 bool SessionModelAssociator::UpdateAssociationsFromSyncModel( | 555 bool SessionModelAssociator::UpdateAssociationsFromSyncModel( |
| 497 const sync_api::ReadNode& root, | 556 const sync_api::ReadNode& root, |
| 498 const sync_api::BaseTransaction* trans) { | 557 const sync_api::BaseTransaction* trans) { |
| 499 DCHECK(CalledOnValidThread()); | 558 DCHECK(CalledOnValidThread()); |
| 500 | 559 |
| 501 // Iterate through the nodes and associate any foreign sessions. | 560 // Iterate through the nodes and associate any foreign sessions. |
| 502 int64 id = root.GetFirstChildId(); | 561 int64 id = root.GetFirstChildId(); |
| 503 while (id != sync_api::kInvalidId) { | 562 while (id != sync_api::kInvalidId) { |
| 504 sync_api::ReadNode sync_node(trans); | 563 sync_api::ReadNode sync_node(trans); |
| 505 if (!sync_node.InitByIdLookup(id)) { | 564 if (!sync_node.InitByIdLookup(id)) { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 554 if (specifics.has_header()) { | 613 if (specifics.has_header()) { |
| 555 // Read in the header data for this foreign session. | 614 // Read in the header data for this foreign session. |
| 556 // Header data contains window information and ordered tab id's for each | 615 // Header data contains window information and ordered tab id's for each |
| 557 // window. | 616 // window. |
| 558 | 617 |
| 559 // Load (or create) the SyncedSession object for this client. | 618 // Load (or create) the SyncedSession object for this client. |
| 560 SyncedSession* foreign_session = | 619 SyncedSession* foreign_session = |
| 561 synced_session_tracker_.GetSession(foreign_session_tag); | 620 synced_session_tracker_.GetSession(foreign_session_tag); |
| 562 | 621 |
| 563 const sync_pb::SessionHeader& header = specifics.header(); | 622 const sync_pb::SessionHeader& header = specifics.header(); |
| 623 PopulateSessionHeaderFromSpecifics(header, foreign_session); | |
| 564 foreign_session->windows.reserve(header.window_size()); | 624 foreign_session->windows.reserve(header.window_size()); |
| 565 VLOG(1) << "Associating " << foreign_session_tag << " with " << | 625 VLOG(1) << "Associating " << foreign_session_tag << " with " << |
| 566 header.window_size() << " windows."; | 626 header.window_size() << " windows."; |
| 567 size_t i; | 627 size_t i; |
| 568 for (i = 0; i < static_cast<size_t>(header.window_size()); ++i) { | 628 for (i = 0; i < static_cast<size_t>(header.window_size()); ++i) { |
| 569 if (i >= foreign_session->windows.size()) { | 629 if (i >= foreign_session->windows.size()) { |
| 570 // This a new window, create it. | 630 // This a new window, create it. |
| 571 foreign_session->windows.push_back(new SessionWindow()); | 631 foreign_session->windows.push_back(new SessionWindow()); |
| 572 } | 632 } |
| 573 const sync_pb::SessionWindow& window_s = header.window(i); | 633 const sync_pb::SessionWindow& window_s = header.window(i); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 598 return true; | 658 return true; |
| 599 } | 659 } |
| 600 | 660 |
| 601 void SessionModelAssociator::DisassociateForeignSession( | 661 void SessionModelAssociator::DisassociateForeignSession( |
| 602 const std::string& foreign_session_tag) { | 662 const std::string& foreign_session_tag) { |
| 603 DCHECK(CalledOnValidThread()); | 663 DCHECK(CalledOnValidThread()); |
| 604 synced_session_tracker_.DeleteSession(foreign_session_tag); | 664 synced_session_tracker_.DeleteSession(foreign_session_tag); |
| 605 } | 665 } |
| 606 | 666 |
| 607 // Static | 667 // Static |
| 668 void SessionModelAssociator::PopulateSessionHeaderFromSpecifics( | |
| 669 const sync_pb::SessionHeader& header_specifics, | |
| 670 SyncedSession* session_header) { | |
| 671 if (header_specifics.has_client_name()) { | |
| 672 session_header->client_name = header_specifics.client_name(); | |
| 673 } | |
| 674 if (header_specifics.has_device_type()) { | |
| 675 switch (header_specifics.device_type()) { | |
| 676 case sync_pb::SessionHeader_DeviceType_TYPE_WIN: | |
| 677 session_header->device_type = SyncedSession::TYPE_WIN; | |
| 678 break; | |
| 679 case sync_pb::SessionHeader_DeviceType_TYPE_MAC: | |
| 680 session_header->device_type = SyncedSession::TYPE_MAC; | |
| 681 break; | |
| 682 case sync_pb::SessionHeader_DeviceType_TYPE_LINUX: | |
| 683 session_header->device_type = SyncedSession::TYPE_LINUX; | |
| 684 break; | |
| 685 case sync_pb::SessionHeader_DeviceType_TYPE_CROS: | |
| 686 session_header->device_type = SyncedSession::TYPE_CROS; | |
| 687 break; | |
| 688 case sync_pb::SessionHeader_DeviceType_TYPE_OTHER: | |
| 689 // Intentionally fall-through | |
| 690 default: | |
| 691 session_header->device_type = SyncedSession::TYPE_OTHER; | |
| 692 break; | |
| 693 } | |
| 694 } | |
| 695 } | |
| 696 | |
| 697 // Static | |
| 608 void SessionModelAssociator::PopulateSessionWindowFromSpecifics( | 698 void SessionModelAssociator::PopulateSessionWindowFromSpecifics( |
| 609 const std::string& session_tag, | 699 const std::string& session_tag, |
| 610 const sync_pb::SessionWindow& specifics, | 700 const sync_pb::SessionWindow& specifics, |
| 611 int64 mtime, | 701 int64 mtime, |
| 612 SessionWindow* session_window, | 702 SessionWindow* session_window, |
| 613 SyncedSessionTracker* tracker) { | 703 SyncedSessionTracker* tracker) { |
| 614 if (specifics.has_window_id()) | 704 if (specifics.has_window_id()) |
| 615 session_window->window_id.set_id(specifics.window_id()); | 705 session_window->window_id.set_id(specifics.window_id()); |
| 616 if (specifics.has_selected_tab_index()) | 706 if (specifics.has_selected_tab_index()) |
| 617 session_window->selected_tab_index = specifics.selected_tab_index(); | 707 session_window->selected_tab_index = specifics.selected_tab_index(); |
| (...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1070 bool SessionModelAssociator::CryptoReadyIfNecessary() { | 1160 bool SessionModelAssociator::CryptoReadyIfNecessary() { |
| 1071 // We only access the cryptographer while holding a transaction. | 1161 // We only access the cryptographer while holding a transaction. |
| 1072 sync_api::ReadTransaction trans(FROM_HERE, sync_service_->GetUserShare()); | 1162 sync_api::ReadTransaction trans(FROM_HERE, sync_service_->GetUserShare()); |
| 1073 syncable::ModelTypeSet encrypted_types; | 1163 syncable::ModelTypeSet encrypted_types; |
| 1074 encrypted_types = sync_api::GetEncryptedTypes(&trans); | 1164 encrypted_types = sync_api::GetEncryptedTypes(&trans); |
| 1075 return encrypted_types.count(syncable::SESSIONS) == 0 || | 1165 return encrypted_types.count(syncable::SESSIONS) == 0 || |
| 1076 sync_service_->IsCryptographerReady(&trans); | 1166 sync_service_->IsCryptographerReady(&trans); |
| 1077 } | 1167 } |
| 1078 | 1168 |
| 1079 } // namespace browser_sync | 1169 } // namespace browser_sync |
| OLD | NEW |