Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(351)

Side by Side Diff: chrome/browser/sync/glue/session_model_associator.cc

Issue 7792102: Revert 99391 (broke CrOS unit_tests) - Set user-visible machine names and devices types for synce... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/sys_info.h"
13 #include "base/tracked.h" 12 #include "base/tracked.h"
14 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/profiles/profile.h" 13 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/sessions/session_service_factory.h" 14 #include "chrome/browser/sessions/session_service_factory.h"
17 #include "chrome/browser/sync/api/sync_error.h" 15 #include "chrome/browser/sync/api/sync_error.h"
18 #include "chrome/browser/sync/glue/synced_session.h"
19 #include "chrome/browser/sync/glue/synced_tab_delegate.h" 16 #include "chrome/browser/sync/glue/synced_tab_delegate.h"
20 #include "chrome/browser/sync/glue/synced_window_delegate.h" 17 #include "chrome/browser/sync/glue/synced_window_delegate.h"
21 #include "chrome/browser/sync/internal_api/read_node.h" 18 #include "chrome/browser/sync/internal_api/read_node.h"
22 #include "chrome/browser/sync/internal_api/read_transaction.h" 19 #include "chrome/browser/sync/internal_api/read_transaction.h"
23 #include "chrome/browser/sync/internal_api/write_node.h" 20 #include "chrome/browser/sync/internal_api/write_node.h"
24 #include "chrome/browser/sync/internal_api/write_transaction.h" 21 #include "chrome/browser/sync/internal_api/write_transaction.h"
25 #include "chrome/browser/sync/profile_sync_service.h" 22 #include "chrome/browser/sync/profile_sync_service.h"
26 #include "chrome/browser/sync/syncable/syncable.h" 23 #include "chrome/browser/sync/syncable/syncable.h"
27 #include "chrome/common/chrome_notification_types.h" 24 #include "chrome/common/chrome_notification_types.h"
28 #include "chrome/common/url_constants.h" 25 #include "chrome/common/url_constants.h"
29 #include "content/browser/tab_contents/navigation_entry.h" 26 #include "content/browser/tab_contents/navigation_entry.h"
30 #include "content/common/notification_details.h" 27 #include "content/common/notification_details.h"
31 #include "content/common/notification_service.h" 28 #include "content/common/notification_service.h"
32 #if defined(OS_LINUX)
33 #include "base/linux_util.h"
34 #elif defined(OS_WIN)
35 #include <windows.h>
36 #endif
37 29
38 namespace browser_sync { 30 namespace browser_sync {
39 31
40 namespace { 32 namespace {
41 static const char kNoSessionsFolderError[] = 33 static const char kNoSessionsFolderError[] =
42 "Server did not create the top-level sessions node. We " 34 "Server did not create the top-level sessions node. We "
43 "might be running against an out-of-date server."; 35 "might be running against an out-of-date server.";
44 36
45 // The maximum number of navigations in each direction we care to sync. 37 // The maximum number of navigations in each direction we care to sync.
46 static const int max_sync_navigation_count = 6; 38 static const int max_sync_navigation_count = 6;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 } 116 }
125 117
126 void SessionModelAssociator::ReassociateWindows(bool reload_tabs) { 118 void SessionModelAssociator::ReassociateWindows(bool reload_tabs) {
127 DCHECK(CalledOnValidThread()); 119 DCHECK(CalledOnValidThread());
128 std::string local_tag = GetCurrentMachineTag(); 120 std::string local_tag = GetCurrentMachineTag();
129 sync_pb::SessionSpecifics specifics; 121 sync_pb::SessionSpecifics specifics;
130 specifics.set_session_tag(local_tag); 122 specifics.set_session_tag(local_tag);
131 sync_pb::SessionHeader* header_s = specifics.mutable_header(); 123 sync_pb::SessionHeader* header_s = specifics.mutable_header();
132 SyncedSession* current_session = 124 SyncedSession* current_session =
133 synced_session_tracker_.GetSession(local_tag); 125 synced_session_tracker_.GetSession(local_tag);
134 header_s->set_client_name(current_session_name_);
135 #if defined(OS_LINUX)
136 header_s->set_device_type(sync_pb::SessionHeader_DeviceType_TYPE_LINUX);
137 #elif defined(OS_MACOSX)
138 header_s->set_device_type(sync_pb::SessionHeader_DeviceType_TYPE_MAC);
139 #elif defined(OS_WIN)
140 header_s->set_device_type(sync_pb::SessionHeader_DeviceType_TYPE_WIN);
141 #elif defined(OS_CHROMEOS)
142 header_s->set_device_type(sync_pb::SessionHeader_DeviceType_TYPE_CROS);
143 #else
144 header_s->set_device_type(sync_pb::SessionHeader_DeviceType_TYPE_OTHER);
145 #endif
146 126
147 size_t window_num = 0; 127 size_t window_num = 0;
148 std::set<SyncedWindowDelegate*> windows = 128 std::set<SyncedWindowDelegate*> windows =
149 SyncedWindowDelegate::GetSyncedWindowDelegates(); 129 SyncedWindowDelegate::GetSyncedWindowDelegates();
150 current_session->windows.reserve(windows.size()); 130 current_session->windows.reserve(windows.size());
151 for (std::set<SyncedWindowDelegate*>::const_iterator i = 131 for (std::set<SyncedWindowDelegate*>::const_iterator i =
152 windows.begin(); i != windows.end(); ++i) { 132 windows.begin(); i != windows.end(); ++i) {
153 // Make sure the window has tabs and a viewable window. The viewable window 133 // Make sure the window has tabs and a viewable window. The viewable window
154 // check is necessary because, for example, when a browser is closed the 134 // check is necessary because, for example, when a browser is closed the
155 // destructor is not necessarily run immediately. This means its possible 135 // destructor is not necessarily run immediately. This means its possible
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 { 420 {
441 sync_api::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare()); 421 sync_api::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare());
442 422
443 sync_api::ReadNode root(&trans); 423 sync_api::ReadNode root(&trans);
444 if (!root.InitByTagLookup(kSessionsTag)) { 424 if (!root.InitByTagLookup(kSessionsTag)) {
445 error->Reset(FROM_HERE, kNoSessionsFolderError, model_type()); 425 error->Reset(FROM_HERE, kNoSessionsFolderError, model_type());
446 return false; 426 return false;
447 } 427 }
448 428
449 // Make sure we have a machine tag. 429 // Make sure we have a machine tag.
450 if (current_machine_tag_.empty()) { 430 if (current_machine_tag_.empty())
451 InitializeCurrentMachineTag(&trans); 431 InitializeCurrentMachineTag(&trans);
452 // The session name is retrieved asynchronously so it might not come back
453 // for the writing of the session. However, we write to the session often
454 // enough (on every navigation) that we'll pick it up quickly.
455 InitializeCurrentSessionName();
456 }
457 synced_session_tracker_.SetLocalSessionTag(current_machine_tag_); 432 synced_session_tracker_.SetLocalSessionTag(current_machine_tag_);
458 if (!UpdateAssociationsFromSyncModel(root, &trans)) { 433 if (!UpdateAssociationsFromSyncModel(root, &trans)) {
459 error->Reset(FROM_HERE, 434 error->Reset(FROM_HERE,
460 "Failed to update associations from sync", 435 "Failed to update associations from sync",
461 model_type()); 436 model_type());
462 return false; 437 return false;
463 } 438 }
464 439
465 if (local_session_syncid_ == sync_api::kInvalidId) { 440 if (local_session_syncid_ == sync_api::kInvalidId) {
466 // The sync db didn't have a header node for us, we need to create one. 441 // The sync db didn't have a header node for us, we need to create one.
(...skipping 17 matching lines...) Expand all
484 459
485 return true; 460 return true;
486 } 461 }
487 462
488 bool SessionModelAssociator::DisassociateModels(SyncError* error) { 463 bool SessionModelAssociator::DisassociateModels(SyncError* error) {
489 DCHECK(CalledOnValidThread()); 464 DCHECK(CalledOnValidThread());
490 synced_session_tracker_.clear(); 465 synced_session_tracker_.clear();
491 tab_map_.clear(); 466 tab_map_.clear();
492 tab_pool_.clear(); 467 tab_pool_.clear();
493 local_session_syncid_ = sync_api::kInvalidId; 468 local_session_syncid_ = sync_api::kInvalidId;
494 current_machine_tag_ = "";
495 current_session_name_ = "";
496 469
497 // There is no local model stored with which to disassociate, just notify 470 // There is no local model stored with which to disassociate, just notify
498 // foreign session handlers. 471 // foreign session handlers.
499 NotificationService::current()->Notify( 472 NotificationService::current()->Notify(
500 chrome::NOTIFICATION_FOREIGN_SESSION_DISABLED, 473 chrome::NOTIFICATION_FOREIGN_SESSION_DISABLED,
501 NotificationService::AllSources(), 474 NotificationService::AllSources(),
502 NotificationService::NoDetails()); 475 NotificationService::NoDetails());
503 return true; 476 return true;
504 } 477 }
505 478
506 void SessionModelAssociator::InitializeCurrentMachineTag( 479 void SessionModelAssociator::InitializeCurrentMachineTag(
507 sync_api::WriteTransaction* trans) { 480 sync_api::WriteTransaction* trans) {
508 DCHECK(CalledOnValidThread()); 481 DCHECK(CalledOnValidThread());
509 syncable::Directory* dir = trans->GetWrappedWriteTrans()->directory(); 482 syncable::Directory* dir = trans->GetWrappedWriteTrans()->directory();
483
484 // TODO(zea): We need a better way of creating a machine tag. The directory
485 // 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
487 // the server since that tag will not be reused. Eventually this should
488 // become some string identifiable to the user. (Home, Work, Laptop, etc.)
489 // See issue at http://crbug.com/59672
510 current_machine_tag_ = "session_sync"; 490 current_machine_tag_ = "session_sync";
511 current_machine_tag_.append(dir->cache_guid()); 491 current_machine_tag_.append(dir->cache_guid());
512 VLOG(1) << "Creating machine tag: " << current_machine_tag_; 492 VLOG(1) << "Creating machine tag: " << current_machine_tag_;
513 tab_pool_.set_machine_tag(current_machine_tag_); 493 tab_pool_.set_machine_tag(current_machine_tag_);
514 } 494 }
515 495
516 void SessionModelAssociator::OnSessionNameInitialized(const std::string name) {
517 DCHECK(CalledOnValidThread());
518 // Only use the default machine name if it hasn't already been set.
519 if (current_session_name_.empty()) {
520 current_session_name_ = name;
521 }
522 }
523
524 // Task which runs on the file thread because it runs system calls which can
525 // block while retrieving sytem information.
526 class GetSessionNameTask : public Task {
527 public:
528 explicit GetSessionNameTask(
529 const WeakHandle<SessionModelAssociator> associator) :
530 associator_(associator) {}
531
532 virtual void Run() {
533 #if defined(OS_LINUX)
534 std::string session_name = base::GetLinuxDistro();
535 #elif defined(OS_MACOSX)
536 std::string session_name = SessionModelAssociator::GetHardwareModelName();
537 #elif defined(OS_WIN)
538 std::string session_name = SessionModelAssociator::GetComputerName();
539 #else
540 std::string session_name;
541 #endif
542 if (session_name == "Unknown" || session_name.empty()) {
543 session_name = base::SysInfo::OperatingSystemName();
544 }
545 associator_.Call(FROM_HERE,
546 &SessionModelAssociator::OnSessionNameInitialized,
547 session_name);
548 }
549 const WeakHandle<SessionModelAssociator> associator_;
550
551 DISALLOW_COPY_AND_ASSIGN(GetSessionNameTask);
552 };
553
554 void SessionModelAssociator::InitializeCurrentSessionName() {
555 DCHECK(CalledOnValidThread());
556 #if defined(OS_CHROMEOS)
557 OnSessionNameInitialized("Chromebook");
558 #else
559 if (setup_for_test_) {
560 OnSessionNameInitialized("TestSessionName");
561 } else {
562 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
563 new GetSessionNameTask(MakeWeakHandle(AsWeakPtr())));
564 }
565 #endif
566 }
567
568 bool SessionModelAssociator::UpdateAssociationsFromSyncModel( 496 bool SessionModelAssociator::UpdateAssociationsFromSyncModel(
569 const sync_api::ReadNode& root, 497 const sync_api::ReadNode& root,
570 const sync_api::BaseTransaction* trans) { 498 const sync_api::BaseTransaction* trans) {
571 DCHECK(CalledOnValidThread()); 499 DCHECK(CalledOnValidThread());
572 500
573 // Iterate through the nodes and associate any foreign sessions. 501 // Iterate through the nodes and associate any foreign sessions.
574 int64 id = root.GetFirstChildId(); 502 int64 id = root.GetFirstChildId();
575 while (id != sync_api::kInvalidId) { 503 while (id != sync_api::kInvalidId) {
576 sync_api::ReadNode sync_node(trans); 504 sync_api::ReadNode sync_node(trans);
577 if (!sync_node.InitByIdLookup(id)) { 505 if (!sync_node.InitByIdLookup(id)) {
578 LOG(ERROR) << "Failed to fetch sync node for id " << id; 506 LOG(ERROR) << "Failed to fetch sync node for id " << id;
579 return false; 507 return false;
580 } 508 }
581 509
582 const sync_pb::SessionSpecifics& specifics = 510 const sync_pb::SessionSpecifics& specifics =
583 sync_node.GetSessionSpecifics(); 511 sync_node.GetSessionSpecifics();
584 const int64 modification_time = sync_node.GetModificationTime(); 512 const int64 modification_time = sync_node.GetModificationTime();
585 if (specifics.session_tag() != GetCurrentMachineTag()) { 513 if (specifics.session_tag() != GetCurrentMachineTag()) {
586 if (!AssociateForeignSpecifics(specifics, modification_time)) { 514 if (!AssociateForeignSpecifics(specifics, modification_time)) {
587 return false; 515 return false;
588 } 516 }
589 } else if (id != local_session_syncid_) { 517 } else if (id != local_session_syncid_) {
590 // This is previously stored local session information. 518 // This is previously stored local session information.
591 if (specifics.has_header()) { 519 if (specifics.has_header()) {
592 if (sync_api::kInvalidId != local_session_syncid_) 520 if (sync_api::kInvalidId != local_session_syncid_)
593 return false; 521 return false;
594 522
595 // This is our previous header node, reuse it. 523 // This is our previous header node, reuse it.
596 local_session_syncid_ = id; 524 local_session_syncid_ = id;
597 if (specifics.header().has_client_name()) {
598 current_session_name_ = specifics.header().client_name();
599 }
600 } else { 525 } else {
601 if (!specifics.has_tab()) 526 if (!specifics.has_tab())
602 return false; 527 return false;
603 528
604 // This is a tab node. We want to track these to reuse them in our free 529 // This is a tab node. We want to track these to reuse them in our free
605 // tab node pool. They will be overwritten eventually, so need to do 530 // tab node pool. They will be overwritten eventually, so need to do
606 // anything else. 531 // anything else.
607 tab_pool_.AddTabNode(id); 532 tab_pool_.AddTabNode(id);
608 } 533 }
609 } 534 }
(...skipping 19 matching lines...) Expand all
629 if (specifics.has_header()) { 554 if (specifics.has_header()) {
630 // Read in the header data for this foreign session. 555 // Read in the header data for this foreign session.
631 // Header data contains window information and ordered tab id's for each 556 // Header data contains window information and ordered tab id's for each
632 // window. 557 // window.
633 558
634 // Load (or create) the SyncedSession object for this client. 559 // Load (or create) the SyncedSession object for this client.
635 SyncedSession* foreign_session = 560 SyncedSession* foreign_session =
636 synced_session_tracker_.GetSession(foreign_session_tag); 561 synced_session_tracker_.GetSession(foreign_session_tag);
637 562
638 const sync_pb::SessionHeader& header = specifics.header(); 563 const sync_pb::SessionHeader& header = specifics.header();
639 PopulateSessionHeaderFromSpecifics(header, foreign_session);
640 foreign_session->windows.reserve(header.window_size()); 564 foreign_session->windows.reserve(header.window_size());
641 VLOG(1) << "Associating " << foreign_session_tag << " with " << 565 VLOG(1) << "Associating " << foreign_session_tag << " with " <<
642 header.window_size() << " windows."; 566 header.window_size() << " windows.";
643 size_t i; 567 size_t i;
644 for (i = 0; i < static_cast<size_t>(header.window_size()); ++i) { 568 for (i = 0; i < static_cast<size_t>(header.window_size()); ++i) {
645 if (i >= foreign_session->windows.size()) { 569 if (i >= foreign_session->windows.size()) {
646 // This a new window, create it. 570 // This a new window, create it.
647 foreign_session->windows.push_back(new SessionWindow()); 571 foreign_session->windows.push_back(new SessionWindow());
648 } 572 }
649 const sync_pb::SessionWindow& window_s = header.window(i); 573 const sync_pb::SessionWindow& window_s = header.window(i);
(...skipping 24 matching lines...) Expand all
674 return true; 598 return true;
675 } 599 }
676 600
677 void SessionModelAssociator::DisassociateForeignSession( 601 void SessionModelAssociator::DisassociateForeignSession(
678 const std::string& foreign_session_tag) { 602 const std::string& foreign_session_tag) {
679 DCHECK(CalledOnValidThread()); 603 DCHECK(CalledOnValidThread());
680 synced_session_tracker_.DeleteSession(foreign_session_tag); 604 synced_session_tracker_.DeleteSession(foreign_session_tag);
681 } 605 }
682 606
683 // Static 607 // Static
684 void SessionModelAssociator::PopulateSessionHeaderFromSpecifics(
685 const sync_pb::SessionHeader& header_specifics,
686 SyncedSession* session_header) {
687 if (header_specifics.has_client_name()) {
688 session_header->session_name = header_specifics.client_name();
689 }
690 if (header_specifics.has_device_type()) {
691 switch (header_specifics.device_type()) {
692 case sync_pb::SessionHeader_DeviceType_TYPE_WIN:
693 session_header->device_type = SyncedSession::TYPE_WIN;
694 break;
695 case sync_pb::SessionHeader_DeviceType_TYPE_MAC:
696 session_header->device_type = SyncedSession::TYPE_MACOSX;
697 break;
698 case sync_pb::SessionHeader_DeviceType_TYPE_LINUX:
699 session_header->device_type = SyncedSession::TYPE_LINUX;
700 break;
701 case sync_pb::SessionHeader_DeviceType_TYPE_CROS:
702 session_header->device_type = SyncedSession::TYPE_CHROMEOS;
703 break;
704 case sync_pb::SessionHeader_DeviceType_TYPE_OTHER:
705 // Intentionally fall-through
706 default:
707 session_header->device_type = SyncedSession::TYPE_OTHER;
708 break;
709 }
710 }
711 }
712
713 // Static
714 void SessionModelAssociator::PopulateSessionWindowFromSpecifics( 608 void SessionModelAssociator::PopulateSessionWindowFromSpecifics(
715 const std::string& session_tag, 609 const std::string& session_tag,
716 const sync_pb::SessionWindow& specifics, 610 const sync_pb::SessionWindow& specifics,
717 int64 mtime, 611 int64 mtime,
718 SessionWindow* session_window, 612 SessionWindow* session_window,
719 SyncedSessionTracker* tracker) { 613 SyncedSessionTracker* tracker) {
720 if (specifics.has_window_id()) 614 if (specifics.has_window_id())
721 session_window->window_id.set_id(specifics.window_id()); 615 session_window->window_id.set_id(specifics.window_id());
722 if (specifics.has_selected_tab_index()) 616 if (specifics.has_selected_tab_index())
723 session_window->selected_tab_index = specifics.selected_tab_index(); 617 session_window->selected_tab_index = specifics.selected_tab_index();
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after
1175 1069
1176 bool SessionModelAssociator::CryptoReadyIfNecessary() { 1070 bool SessionModelAssociator::CryptoReadyIfNecessary() {
1177 // We only access the cryptographer while holding a transaction. 1071 // We only access the cryptographer while holding a transaction.
1178 sync_api::ReadTransaction trans(FROM_HERE, sync_service_->GetUserShare()); 1072 sync_api::ReadTransaction trans(FROM_HERE, sync_service_->GetUserShare());
1179 syncable::ModelTypeSet encrypted_types; 1073 syncable::ModelTypeSet encrypted_types;
1180 encrypted_types = sync_api::GetEncryptedTypes(&trans); 1074 encrypted_types = sync_api::GetEncryptedTypes(&trans);
1181 return encrypted_types.count(syncable::SESSIONS) == 0 || 1075 return encrypted_types.count(syncable::SESSIONS) == 0 ||
1182 sync_service_->IsCryptographerReady(&trans); 1076 sync_service_->IsCryptographerReady(&trans);
1183 } 1077 }
1184 1078
1185 #if defined(OS_WIN)
1186 // Static
1187 // TODO(nzea): This isn't safe to call on the UI-thread. Move it out to a util
1188 // or object that lives on the FILE thread.
1189 std::string SessionModelAssociator::GetComputerName() {
1190 char computer_name[MAX_COMPUTERNAME_LENGTH + 1];
1191 DWORD size = sizeof(computer_name);
1192 if (GetComputerNameA(computer_name, &size)) {
1193 return computer_name;
1194 }
1195 return std::string();
1196 }
1197 #endif
1198
1199 } // namespace browser_sync 1079 } // namespace browser_sync
OLDNEW
« no previous file with comments | « chrome/browser/sync/glue/session_model_associator.h ('k') | chrome/browser/sync/glue/session_model_associator_mac.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698