Chromium Code Reviews| Index: chrome/browser/sync/glue/session_model_associator.cc |
| diff --git a/chrome/browser/sync/glue/session_model_associator.cc b/chrome/browser/sync/glue/session_model_associator.cc |
| index ea4eee306bb0bbd0728373c23140fc6cdd5311fd..2696f6565993e29ea6148c11a08c36d47b8cbdab 100644 |
| --- a/chrome/browser/sync/glue/session_model_associator.cc |
| +++ b/chrome/browser/sync/glue/session_model_associator.cc |
| @@ -9,10 +9,13 @@ |
| #include <utility> |
| #include "base/logging.h" |
| +#include "base/sys_info.h" |
| #include "base/tracked.h" |
| +#include "chrome/browser/browser_process.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/sessions/session_service_factory.h" |
| #include "chrome/browser/sync/api/sync_error.h" |
| +#include "chrome/browser/sync/glue/synced_session.h" |
| #include "chrome/browser/sync/glue/synced_tab_delegate.h" |
| #include "chrome/browser/sync/glue/synced_window_delegate.h" |
| #include "chrome/browser/sync/internal_api/read_node.h" |
| @@ -26,6 +29,9 @@ |
| #include "content/browser/tab_contents/navigation_entry.h" |
| #include "content/common/notification_details.h" |
| #include "content/common/notification_service.h" |
| +#if defined(OS_LINUX) |
| +#include "base/linux_util.h" |
| +#endif |
| namespace browser_sync { |
| @@ -123,6 +129,18 @@ void SessionModelAssociator::ReassociateWindows(bool reload_tabs) { |
| sync_pb::SessionHeader* header_s = specifics.mutable_header(); |
| SyncedSession* current_session = |
| synced_session_tracker_.GetSession(local_tag); |
| + header_s->set_client_name(current_session_name_); |
| +#if defined(OS_LINUX) |
| + header_s->set_device_type(sync_pb::SessionHeader_DeviceType_TYPE_LINUX); |
| +#elif defined(OS_MACOSX) |
| + header_s->set_device_type(sync_pb::SessionHeader_DeviceType_TYPE_MAC); |
| +#elif defined(OS_WIN) |
| + header_s->set_device_type(sync_pb::SessionHeader_DeviceType_TYPE_WIN); |
| +#elif defined(OS_CHROMEOS) |
| + header_s->set_device_type(sync_pb::SessionHeader_DeviceType_TYPE_CROS); |
| +#else |
| + header_s->set_device_type(sync_pb::SessionHeader_DeviceType_TYPE_PC); |
|
Nicolas Zea
2011/09/01 00:03:36
Shouldn't this be TYPE_OTHER?
Yaron
2011/09/01 20:16:17
Done.
|
| +#endif |
| size_t window_num = 0; |
| std::set<SyncedWindowDelegate*> windows = |
| @@ -427,8 +445,13 @@ bool SessionModelAssociator::AssociateModels(SyncError* error) { |
| } |
| // Make sure we have a machine tag. |
| - if (current_machine_tag_.empty()) |
| + if (current_machine_tag_.empty()) { |
| InitializeCurrentMachineTag(&trans); |
| + // The session name is retrieved asynchronously so it might not come back |
| + // for the writing of the session. However, we write to the session often |
| + // enough (on every navigation) that we'll pick it up quickly. |
| + InitializeCurrentSessionName(); |
| + } |
| synced_session_tracker_.SetLocalSessionTag(current_machine_tag_); |
| if (!UpdateAssociationsFromSyncModel(root, &trans)) { |
| error->Reset(FROM_HERE, |
| @@ -466,6 +489,8 @@ bool SessionModelAssociator::DisassociateModels(SyncError* error) { |
| tab_map_.clear(); |
| tab_pool_.clear(); |
| local_session_syncid_ = sync_api::kInvalidId; |
| + current_machine_tag_ = ""; |
| + current_session_name_ = ""; |
| // There is no local model stored with which to disassociate, just notify |
| // foreign session handlers. |
| @@ -480,19 +505,64 @@ void SessionModelAssociator::InitializeCurrentMachineTag( |
| sync_api::WriteTransaction* trans) { |
| DCHECK(CalledOnValidThread()); |
| syncable::Directory* dir = trans->GetWrappedWriteTrans()->directory(); |
| - |
| - // TODO(zea): We need a better way of creating a machine tag. The directory |
| - // kernel's cache_guid changes every time syncing is turned on and off. This |
| - // will result in session's associated with stale machine tags persisting on |
| - // the server since that tag will not be reused. Eventually this should |
| - // become some string identifiable to the user. (Home, Work, Laptop, etc.) |
| - // See issue at http://crbug.com/59672 |
| current_machine_tag_ = "session_sync"; |
| current_machine_tag_.append(dir->cache_guid()); |
| VLOG(1) << "Creating machine tag: " << current_machine_tag_; |
| tab_pool_.set_machine_tag(current_machine_tag_); |
| } |
| +void SessionModelAssociator::OnSessionNameInitialized(const std::string name) { |
| + DCHECK(CalledOnValidThread()); |
| + // Only use the default machine name if it hasn't already been set. |
| + if (current_session_name_.empty()) { |
| + current_session_name_ = name; |
| + } |
| +} |
| + |
| +// Task which runs on the file thread because it runs system calls which can |
| +// block while retrieving sytem information. |
| +class GetSessionNameTask : public Task { |
| + public: |
| + explicit GetSessionNameTask( |
| + const WeakHandle<SessionModelAssociator> associator) : |
| + associator_(associator) {} |
| + |
| + virtual void Run() { |
| +#if defined(OS_LINUX) |
| + std::string session_name = base::GetLinuxDistro(); |
| +#elif defined(OS_MACOSX) |
| + std::string session_name = GetHardwareModelName(); |
| +#elif defined(OS_WIN) |
| + std::string session_name = GetComputerName(); |
| +#else |
| + std::string session_name; |
| +#endif |
| + if (session_name == "Unknown" || session_name.empty()) { |
| + session_name = base::SysInfo::OperatingSystemName(); |
| + } |
| + associator_.Call(FROM_HERE, |
| + &SessionModelAssociator::OnSessionNameInitialized, |
| + session_name); |
| + } |
| + const WeakHandle<SessionModelAssociator> associator_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(GetSessionNameTask); |
| +}; |
| + |
| +void SessionModelAssociator::InitializeCurrentSessionName() { |
| + DCHECK(CalledOnValidThread()); |
| +#if defined(OS_CHROMEOS) |
| + OnSessionNameInitialized("Chromebook"); |
| +#else |
| + if (setup_for_test_) { |
| + OnSessionNameInitialized("TestSessionName"); |
| + } else { |
| + g_browser_process->file_thread()->message_loop()->PostTask(FROM_HERE, |
|
Nicolas Zea
2011/09/01 00:03:36
BrowserThread::PostTask(BrowserThread::FILE, ...)
Yaron
2011/09/01 20:16:17
Done.
|
| + new GetSessionNameTask(MakeWeakHandle(AsWeakPtr()))); |
| + } |
| +#endif |
| +} |
| + |
| bool SessionModelAssociator::UpdateAssociationsFromSyncModel( |
| const sync_api::ReadNode& root, |
| const sync_api::BaseTransaction* trans) { |
| @@ -561,6 +631,7 @@ bool SessionModelAssociator::AssociateForeignSpecifics( |
| synced_session_tracker_.GetSession(foreign_session_tag); |
| const sync_pb::SessionHeader& header = specifics.header(); |
| + PopulateSessionHeaderFromSpecifics(header, foreign_session); |
| foreign_session->windows.reserve(header.window_size()); |
| VLOG(1) << "Associating " << foreign_session_tag << " with " << |
| header.window_size() << " windows."; |
| @@ -605,6 +676,36 @@ void SessionModelAssociator::DisassociateForeignSession( |
| } |
| // Static |
| +void SessionModelAssociator::PopulateSessionHeaderFromSpecifics( |
| + const sync_pb::SessionHeader& header_specifics, |
| + SyncedSession* session_header) { |
| + if (header_specifics.has_client_name()) { |
| + session_header->client_name = header_specifics.client_name(); |
| + } |
| + if (header_specifics.has_device_type()) { |
| + switch (header_specifics.device_type()) { |
| + case sync_pb::SessionHeader_DeviceType_TYPE_WIN: |
| + session_header->device_type = SyncedSession::TYPE_WIN; |
| + break; |
| + case sync_pb::SessionHeader_DeviceType_TYPE_MAC: |
| + session_header->device_type = SyncedSession::TYPE_MACOSX; |
| + break; |
| + case sync_pb::SessionHeader_DeviceType_TYPE_LINUX: |
| + session_header->device_type = SyncedSession::TYPE_LINUX; |
| + break; |
| + case sync_pb::SessionHeader_DeviceType_TYPE_CROS: |
| + session_header->device_type = SyncedSession::TYPE_CHROMEOS; |
| + break; |
| + case sync_pb::SessionHeader_DeviceType_TYPE_OTHER: |
| + // Intentionally fall-through |
| + default: |
| + session_header->device_type = SyncedSession::TYPE_OTHER; |
| + break; |
| + } |
| + } |
| +} |
| + |
| +// Static |
| void SessionModelAssociator::PopulateSessionWindowFromSpecifics( |
| const std::string& session_tag, |
| const sync_pb::SessionWindow& specifics, |
| @@ -1076,4 +1177,32 @@ bool SessionModelAssociator::CryptoReadyIfNecessary() { |
| sync_service_->IsCryptographerReady(&trans); |
| } |
| +#if defined(OS_WIN) |
| +std::string SessionModelAssociator::GetComputerName() { |
|
Nicolas Zea
2011/09/01 00:03:36
Given that these are not safe to run on the UI thr
Yaron
2011/09/01 20:16:17
Done. Made them static in the interim
|
| + char computer_name[MAX_COMPUTERNAME_LENGTH + 1]; |
| + DWORD size = sizeof(computer_name); |
| + if (GetComputerNameA(computer_name, &size)) { |
| + return computer_name; |
| + } |
| + return std::string(); |
| +} |
| +#endif |
| + |
| +#if defined(OS_MACOSX) |
| +std::string SessionModelAssociator::GetHardwareModelName() { |
| + char modelBuffer[256]; |
| + size_t length = sizeof(modelBuffer); |
| + if (!sysctlbyname("hw.model", modelBuffer, &length, NULL, 0)) { |
| + for (size_t i = 0; i < length; i++) { |
| + if (IsAsciiDigit(modelBuffer[i])) { |
| + return std::string(modelBuffer, 0, i); |
| + } |
| + } |
| + return std::string(modelBuffer, 0, length); |
| + } else { |
| + return "Unknown"; |
| + } |
| +} |
| +#endif |
| + |
| } // namespace browser_sync |