10529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file. 44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 50529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "chrome/browser/sync/sessions/sessions_sync_manager.h" 64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 70f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "chrome/browser/chrome_notification_types.h" 8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/profiles/profile.h" 94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/sync/glue/synced_tab_delegate.h" 104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/sync/glue/synced_window_delegate.h" 110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "chrome/browser/sync/sessions/sessions_util.h" 120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "chrome/browser/sync/sessions/synced_window_delegates_getter.h" 134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/common/url_constants.h" 141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/sync_driver/local_device_info_provider.h" 154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/favicon_status.h" 164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/navigation_entry.h" 170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "content/public/browser/notification_details.h" 180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "content/public/browser/notification_service.h" 190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "content/public/browser/notification_source.h" 204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/common/url_constants.h" 214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "sync/api/sync_error.h" 224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "sync/api/sync_error_factory.h" 234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "sync/api/sync_merge_result.h" 244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "sync/api/time.h" 254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using content::NavigationEntry; 274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using sessions::SerializedNavigationEntry; 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing sync_driver::DeviceInfo; 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing sync_driver::LocalDeviceInfoProvider; 304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using syncer::SyncChange; 314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using syncer::SyncData; 324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace browser_sync { 344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Maximum number of favicons to sync. 364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// TODO(zea): pull this from the server. 374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)static const int kMaxSyncFavicons = 200; 384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// The maximum number of navigations in each direction we care to sync. 404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)static const int kMaxSyncNavigationCount = 6; 414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// The URL at which the set of synced tabs is displayed. We treat it differently 43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// from all other URL's as accessing it triggers a sync refresh of Sessions. 44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)static const char kNTPOpenTabSyncURL[] = "chrome://newtab/#open_tabs"; 45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Default number of days without activity after which a session is considered 47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// stale and becomes a candidate for garbage collection. 48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)static const size_t kDefaultStaleSessionThresholdDays = 14; // 2 weeks. 49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// |local_device| is owned by ProfileSyncService, its lifetime exceeds 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// lifetime of SessionSyncManager. 524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)SessionsSyncManager::SessionsSyncManager( 534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Profile* profile, 545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LocalDeviceInfoProvider* local_device, 55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<LocalSessionEventRouter> router) 564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : favicon_cache_(profile, kMaxSyncFavicons), 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) local_tab_pool_out_of_sync_(true), 58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) sync_prefs_(profile->GetPrefs()), 594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) profile_(profile), 605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) local_device_(local_device), 610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch local_session_header_node_id_(TabNodePool::kInvalidTabNodeID), 62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) stale_session_threshold_days_(kDefaultStaleSessionThresholdDays), 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) local_event_router_(router.Pass()), 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) synced_window_getter_(new SyncedWindowDelegatesGetter()) { 654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)LocalSessionEventRouter::~LocalSessionEventRouter() {} 68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)SessionsSyncManager::~SessionsSyncManager() { 704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Returns the GUID-based string that should be used for 734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// |SessionsSyncManager::current_machine_tag_|. 744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)static std::string BuildMachineTag(const std::string& cache_guid) { 754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string machine_tag = "session_sync"; 764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) machine_tag.append(cache_guid); 774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return machine_tag; 784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)syncer::SyncMergeResult SessionsSyncManager::MergeDataAndStartSyncing( 814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) syncer::ModelType type, 824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const syncer::SyncDataList& initial_sync_data, 834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<syncer::SyncChangeProcessor> sync_processor, 844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<syncer::SyncErrorFactory> error_handler) { 854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) syncer::SyncMergeResult merge_result(type); 864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(session_tracker_.Empty()); 874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK_EQ(0U, local_tab_pool_.Capacity()); 884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) error_handler_ = error_handler.Pass(); 904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sync_processor_ = sync_processor.Pass(); 914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch local_session_header_node_id_ = TabNodePool::kInvalidTabNodeID; 934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Make sure we have a machine tag. We do this now (versus earlier) as it's 954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // a conveniently safe time to assert sync is ready and the cache_guid is 964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // initialized. 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (current_machine_tag_.empty()) { 984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) InitializeCurrentMachineTag(); 995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // SessionDataTypeController ensures that the local device info 1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // is available before activating this datatype. 1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(local_device_); 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const DeviceInfo* local_device_info = local_device_->GetLocalDeviceInfo(); 1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (local_device_info) { 1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) current_session_name_ = local_device_info->client_name(); 1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) merge_result.set_error(error_handler_->CreateAndUploadError( 1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FROM_HERE, 1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Failed to get local device info.")); 1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return merge_result; 1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_tracker_.SetLocalSessionTag(current_machine_tag_); 1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) syncer::SyncChangeList new_changes; 1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // First, we iterate over sync data to update our session_tracker_. 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syncer::SyncDataList restored_tabs; 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!InitFromSyncModel(initial_sync_data, &restored_tabs, &new_changes)) { 1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // The sync db didn't have a header node for us. Create one. 1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sync_pb::EntitySpecifics specifics; 1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sync_pb::SessionSpecifics* base_specifics = specifics.mutable_session(); 1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base_specifics->set_session_tag(current_machine_tag()); 1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sync_pb::SessionHeader* header_s = base_specifics->mutable_header(); 1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) header_s->set_client_name(current_session_name_); 1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci header_s->set_device_type(local_device_info->device_type()); 1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) syncer::SyncData data = syncer::SyncData::CreateLocalData( 1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) current_machine_tag(), current_session_name_, specifics); 1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) new_changes.push_back(syncer::SyncChange( 1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FROM_HERE, syncer::SyncChange::ACTION_ADD, data)); 1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_ANDROID) 135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string sync_machine_tag(BuildMachineTag( 1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) local_device_->GetLocalSyncCacheGUID())); 1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (current_machine_tag_.compare(sync_machine_tag) != 0) 138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DeleteForeignSessionInternal(sync_machine_tag, &new_changes); 1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif 1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Check if anything has changed on the local client side. 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AssociateWindows(RELOAD_TABS, restored_tabs, &new_changes); 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) local_tab_pool_out_of_sync_ = false; 1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) merge_result.set_error( 1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes)); 147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) local_event_router_->StartRoutingTo(this); 1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return merge_result; 1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void SessionsSyncManager::AssociateWindows( 1534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ReloadTabsOption option, 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const syncer::SyncDataList& restored_tabs, 1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) syncer::SyncChangeList* change_output) { 1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string local_tag = current_machine_tag(); 1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sync_pb::SessionSpecifics specifics; 1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) specifics.set_session_tag(local_tag); 1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sync_pb::SessionHeader* header_s = specifics.mutable_header(); 1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SyncedSession* current_session = session_tracker_.GetSession(local_tag); 1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) current_session->modified_time = base::Time::Now(); 1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) header_s->set_client_name(current_session_name_); 1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // SessionDataTypeController ensures that the local device info 1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // is available before activating this datatype. 1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(local_device_); 1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const DeviceInfo* local_device_info = local_device_->GetLocalDeviceInfo(); 1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci header_s->set_device_type(local_device_info->device_type()); 1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_tracker_.ResetSessionTracking(local_tag); 1704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::set<SyncedWindowDelegate*> windows = 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) synced_window_getter_->GetSyncedWindowDelegates(); 1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (std::set<SyncedWindowDelegate*>::const_iterator i = 1744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) windows.begin(); i != windows.end(); ++i) { 1754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Make sure the window has tabs and a viewable window. The viewable window 1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // check is necessary because, for example, when a browser is closed the 1774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // destructor is not necessarily run immediately. This means its possible 1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // for us to get a handle to a browser that is about to be removed. If 1794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // the tab count is 0 or the window is NULL, the browser is about to be 1804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // deleted, so we ignore it. 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (sessions_util::ShouldSyncWindow(*i) && 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (*i)->GetTabCount() && (*i)->HasWindow()) { 1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sync_pb::SessionWindow window_s; 1844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SessionID::id_type window_id = (*i)->GetSessionId(); 1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DVLOG(1) << "Associating window " << window_id << " with " 1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) << (*i)->GetTabCount() << " tabs."; 1874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) window_s.set_window_id(window_id); 1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Note: We don't bother to set selected tab index anymore. We still 1894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // consume it when receiving foreign sessions, as reading it is free, but 1904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // it triggers too many sync cycles with too little value to make setting 1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // it worthwhile. 1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if ((*i)->IsTypeTabbed()) { 1934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) window_s.set_browser_type( 1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sync_pb::SessionWindow_BrowserType_TYPE_TABBED); 1954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 1964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) window_s.set_browser_type( 1974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sync_pb::SessionWindow_BrowserType_TYPE_POPUP); 1984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool found_tabs = false; 2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (int j = 0; j < (*i)->GetTabCount(); ++j) { 2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SessionID::id_type tab_id = (*i)->GetTabIdAt(j); 2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SyncedTabDelegate* synced_tab = (*i)->GetTabAt(j); 2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // GetTabAt can return a null tab; in that case just skip it. 2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!synced_tab) 2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) continue; 2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!synced_tab->HasWebContents()) { 2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // For tabs without WebContents update the |tab_id|, as it could have 2114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // changed after a session restore. 2124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Note: We cannot check if a tab is valid if it has no WebContents. 2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // We assume any such tab is valid and leave the contents of 2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // corresponding sync node unchanged. 2150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (synced_tab->GetSyncId() > TabNodePool::kInvalidTabNodeID && 2160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch tab_id > TabNodePool::kInvalidTabID) { 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AssociateRestoredPlaceholderTab(*synced_tab, tab_id, 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) restored_tabs, change_output); 2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) found_tabs = true; 2204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) window_s.add_tab(tab_id); 2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) continue; 2234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (RELOAD_TABS == option) 2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AssociateTab(synced_tab, change_output); 2274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // If the tab is valid, it would have been added to the tracker either 2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // by the above AssociateTab call (at association time), or by the 2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // change processor calling AssociateTab for all modified tabs. 2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Therefore, we can key whether this window has valid tabs based on 2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // the tab's presence in the tracker. 2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const SessionTab* tab = NULL; 2344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (session_tracker_.LookupSessionTab(local_tag, tab_id, &tab)) { 2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) found_tabs = true; 2364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) window_s.add_tab(tab_id); 2374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (found_tabs) { 2404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sync_pb::SessionWindow* header_window = header_s->add_window(); 2414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *header_window = window_s; 2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Update this window's representation in the synced session tracker. 2444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_tracker_.PutWindowInSession(local_tag, window_id); 2454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) BuildSyncedSessionFromSpecifics(local_tag, 2464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) window_s, 2474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) current_session->modified_time, 2484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) current_session->windows[window_id]); 2494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) local_tab_pool_.DeleteUnassociatedTabNodes(change_output); 2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_tracker_.CleanupSession(local_tag); 2544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Always update the header. Sync takes care of dropping this update 2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // if the entity specifics are identical (i.e windows, client name did 2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // not change). 2584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sync_pb::EntitySpecifics entity; 2594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) entity.mutable_session()->CopyFrom(specifics); 2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) syncer::SyncData data = syncer::SyncData::CreateLocalData( 2614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) current_machine_tag(), current_session_name_, entity); 2624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) change_output->push_back(syncer::SyncChange( 2634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FROM_HERE, syncer::SyncChange::ACTION_UPDATE, data)); 2644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void SessionsSyncManager::AssociateTab(SyncedTabDelegate* const tab, 2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) syncer::SyncChangeList* change_output) { 2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(tab->HasWebContents()); 2694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SessionID::id_type tab_id = tab->GetSessionId(); 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (tab->profile() != profile_) 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (tab->IsBeingDestroyed()) { 2744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // This tab is closing. 2754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TabLinksMap::iterator tab_iter = local_tab_map_.find(tab_id); 2764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (tab_iter == local_tab_map_.end()) { 2774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // We aren't tracking this tab (for example, sync setting page). 2784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 2794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) local_tab_pool_.FreeTabNode(tab_iter->second->tab_node_id(), 2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) change_output); 2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) local_tab_map_.erase(tab_iter); 2834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 2844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!sessions_util::ShouldSyncTab(*tab)) 2874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 2884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TabLinksMap::iterator local_tab_map_iter = local_tab_map_.find(tab_id); 2904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TabLink* tab_link = NULL; 2914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (local_tab_map_iter == local_tab_map_.end()) { 2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int tab_node_id = tab->GetSyncId(); 2944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // If there is an old sync node for the tab, reuse it. If this is a new 2954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // tab, get a sync node for it. 2964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!local_tab_pool_.IsUnassociatedTabNode(tab_node_id)) { 2974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) tab_node_id = local_tab_pool_.GetFreeTabNode(change_output); 2984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) tab->SetSyncId(tab_node_id); 2994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 3004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) local_tab_pool_.AssociateTabNode(tab_node_id, tab_id); 3014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) tab_link = new TabLink(tab_node_id, tab); 3024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) local_tab_map_[tab_id] = make_linked_ptr<TabLink>(tab_link); 3034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 3044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // This tab is already associated with a sync node, reuse it. 3054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Note: on some platforms the tab object may have changed, so we ensure 3064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // the tab link is up to date. 3074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) tab_link = local_tab_map_iter->second.get(); 3084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) local_tab_map_iter->second->set_tab(tab); 3094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 3104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(tab_link); 3110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK_NE(tab_link->tab_node_id(), TabNodePool::kInvalidTabNodeID); 3124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DVLOG(1) << "Reloading tab " << tab_id << " from window " 3134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) << tab->GetWindowId(); 3144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Write to sync model. 3164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sync_pb::EntitySpecifics specifics; 3174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) LocalTabDelegateToSpecifics(*tab, specifics.mutable_session()); 3184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) syncer::SyncData data = syncer::SyncData::CreateLocalData( 3190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch TabNodePool::TabIdToTag(current_machine_tag_, 3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) tab_link->tab_node_id()), 3214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) current_session_name_, 3224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) specifics); 3234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) change_output->push_back(syncer::SyncChange( 3244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FROM_HERE, syncer::SyncChange::ACTION_UPDATE, data)); 3254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const GURL new_url = GetCurrentVirtualURL(*tab); 3274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (new_url != tab_link->url()) { 3284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) tab_link->set_url(new_url); 3294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) favicon_cache_.OnFaviconVisited(new_url, GetCurrentFaviconURL(*tab)); 3304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 3314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_tracker_.GetSession(current_machine_tag())->modified_time = 3334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Time::Now(); 3344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SessionsSyncManager::RebuildAssociations() { 3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syncer::SyncDataList data( 3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sync_processor_->GetAllSyncData(syncer::SESSIONS)); 3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<syncer::SyncErrorFactory> error_handler(error_handler_.Pass()); 3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<syncer::SyncChangeProcessor> processor(sync_processor_.Pass()); 3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StopSyncing(syncer::SESSIONS); 3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MergeDataAndStartSyncing( 3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syncer::SESSIONS, data, processor.Pass(), error_handler.Pass()); 3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 34703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool SessionsSyncManager::IsValidSessionHeader( 34803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const sync_pb::SessionHeader& header) { 34903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Verify that tab IDs appear only once within a session. 35003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Intended to prevent http://crbug.com/360822. 35103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::set<int> session_tab_ids; 35203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) for (int i = 0; i < header.window_size(); ++i) { 35303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const sync_pb::SessionWindow& window = header.window(i); 35403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) for (int j = 0; j < window.tab_size(); ++j) { 35503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const int tab_id = window.tab(j); 35603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bool success = session_tab_ids.insert(tab_id).second; 35703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (!success) 35803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return false; 35903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 36003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 36103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 36203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return true; 36303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 36403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 365a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void SessionsSyncManager::OnLocalTabModified(SyncedTabDelegate* modified_tab) { 366a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const content::NavigationEntry* entry = modified_tab->GetActiveEntry(); 367a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!modified_tab->IsBeingDestroyed() && 368a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) entry && 369a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) entry->GetVirtualURL().is_valid() && 370a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) entry->GetVirtualURL().spec() == kNTPOpenTabSyncURL) { 371a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DVLOG(1) << "Triggering sync refresh for sessions datatype."; 372a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const syncer::ModelTypeSet types(syncer::SESSIONS); 373a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) content::NotificationService::current()->Notify( 374a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) chrome::NOTIFICATION_SYNC_REFRESH_LOCAL, 375a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) content::Source<Profile>(profile_), 376a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) content::Details<const syncer::ModelTypeSet>(&types)); 377a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 378a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (local_tab_pool_out_of_sync_) { 3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If our tab pool is corrupt, pay the price of a full re-association to 3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // fix things up. This takes care of the new tab modification as well. 3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RebuildAssociations(); 3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!local_tab_pool_out_of_sync_); 3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 387a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) syncer::SyncChangeList changes; 388a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Associate tabs first so the synced session tracker is aware of them. 389a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AssociateTab(modified_tab, &changes); 390a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Note, we always associate windows because it's possible a tab became 391a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // "interesting" by going to a valid URL, in which case it needs to be added 392a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // to the window's tab information. 3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AssociateWindows(DONT_RELOAD_TABS, syncer::SyncDataList(), &changes); 394a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) sync_processor_->ProcessSyncChanges(FROM_HERE, changes); 3954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 397a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void SessionsSyncManager::OnFaviconPageUrlsUpdated( 398a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::set<GURL>& updated_favicon_page_urls) { 399a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // TODO(zea): consider a separate container for tabs with outstanding favicon 400a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // loads so we don't have to iterate through all tabs comparing urls. 401a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (std::set<GURL>::const_iterator i = updated_favicon_page_urls.begin(); 402a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) i != updated_favicon_page_urls.end(); ++i) { 403a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (TabLinksMap::iterator tab_iter = local_tab_map_.begin(); 404a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) tab_iter != local_tab_map_.end(); 405a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ++tab_iter) { 406a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (tab_iter->second->url() == *i) 407a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) favicon_cache_.OnPageFaviconUpdated(*i); 408a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 409a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 4104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 4114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SessionsSyncManager::StopSyncing(syncer::ModelType type) { 4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) local_event_router_->Stop(); 4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sync_processor_.reset(NULL); 4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error_handler_.reset(); 4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session_tracker_.Clear(); 4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) local_tab_map_.clear(); 4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) local_tab_pool_.Clear(); 4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) current_machine_tag_.clear(); 4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) current_session_name_.clear(); 4210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch local_session_header_node_id_ = TabNodePool::kInvalidTabNodeID; 4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)syncer::SyncDataList SessionsSyncManager::GetAllSyncData( 4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syncer::ModelType type) const { 4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syncer::SyncDataList list; 4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const SyncedSession* session = NULL; 4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!session_tracker_.LookupLocalSession(&session)) 4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return syncer::SyncDataList(); 4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // First construct the header node. 4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sync_pb::EntitySpecifics header_entity; 4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) header_entity.mutable_session()->set_session_tag(current_machine_tag()); 4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sync_pb::SessionHeader* header_specifics = 4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) header_entity.mutable_session()->mutable_header(); 4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) header_specifics->MergeFrom(session->ToSessionHeader()); 4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syncer::SyncData data = syncer::SyncData::CreateLocalData( 4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) current_machine_tag(), current_session_name_, header_entity); 4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) list.push_back(data); 4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SyncedSession::SyncedWindowMap::const_iterator win_iter; 4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (win_iter = session->windows.begin(); 4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) win_iter != session->windows.end(); ++win_iter) { 4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<SessionTab*>::const_iterator tabs_iter; 4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (tabs_iter = win_iter->second->tabs.begin(); 4465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) tabs_iter != win_iter->second->tabs.end(); ++tabs_iter) { 4475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sync_pb::EntitySpecifics entity; 4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sync_pb::SessionSpecifics* specifics = entity.mutable_session(); 4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) specifics->mutable_tab()->MergeFrom((*tabs_iter)->ToSyncData()); 4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) specifics->set_session_tag(current_machine_tag_); 4515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TabLinksMap::const_iterator tab_map_iter = local_tab_map_.find( 4535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (*tabs_iter)->tab_id.id()); 4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(tab_map_iter != local_tab_map_.end()); 4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) specifics->set_tab_node_id(tab_map_iter->second->tab_node_id()); 4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syncer::SyncData data = syncer::SyncData::CreateLocalData( 4570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch TabNodePool::TabIdToTag(current_machine_tag_, 4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) specifics->tab_node_id()), 4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) current_session_name_, 4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) entity); 4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) list.push_back(data); 4624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 4634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return list; 4654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 4664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool SessionsSyncManager::GetLocalSession( 4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const SyncedSession* * local_session) { 4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (current_machine_tag_.empty()) 4704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return false; 4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *local_session = session_tracker_.GetSession(current_machine_tag()); 4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 4734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 4744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)syncer::SyncError SessionsSyncManager::ProcessSyncChanges( 4764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const tracked_objects::Location& from_here, 4774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const syncer::SyncChangeList& change_list) { 4780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (!sync_processor_.get()) { 4790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) syncer::SyncError error(FROM_HERE, 4800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) syncer::SyncError::DATATYPE_ERROR, 4810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) "Models not yet associated.", 4820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) syncer::SESSIONS); 4830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return error; 4840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 4850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 4860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) for (syncer::SyncChangeList::const_iterator it = change_list.begin(); 4870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) it != change_list.end(); ++it) { 4880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) DCHECK(it->IsValid()); 4890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) DCHECK(it->sync_data().GetSpecifics().has_session()); 4900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) const sync_pb::SessionSpecifics& session = 4910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) it->sync_data().GetSpecifics().session(); 4920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) switch (it->change_type()) { 4930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) case syncer::SyncChange::ACTION_DELETE: 4940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Deletions are all or nothing (since we only ever delete entire 4950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // sessions). Therefore we don't care if it's a tab node or meta node, 4960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // and just ensure we've disassociated. 4970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (current_machine_tag() == session.session_tag()) { 4980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Another client has attempted to delete our local data (possibly by 4990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // error or a clock is inaccurate). Just ignore the deletion for now 5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // to avoid any possible ping-pong delete/reassociate sequence, but 5015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // remember that this happened as our TabNodePool is inconsistent. 5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) local_tab_pool_out_of_sync_ = true; 5030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) LOG(WARNING) << "Local session data deleted. Ignoring until next " 5040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) << "local navigation event."; 5050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } else if (session.has_header()) { 5060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Disassociate only when header node is deleted. For tab node 5070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // deletions, the header node will be updated and foreign tab will 5080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // get deleted. 5090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) DisassociateForeignSession(session.session_tag()); 5100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 5110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) continue; 5120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) case syncer::SyncChange::ACTION_ADD: 5130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) case syncer::SyncChange::ACTION_UPDATE: 5140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (current_machine_tag() == session.session_tag()) { 5150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // We should only ever receive a change to our own machine's session 5160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // info if encryption was turned on. In that case, the data is still 5170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // the same, so we can ignore. 5180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) LOG(WARNING) << "Dropping modification to local session."; 5190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return syncer::SyncError(); 5200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 5210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) UpdateTrackerWithForeignSession( 522e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch session, syncer::SyncDataRemote(it->sync_data()).GetModifiedTime()); 5230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) break; 5240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) default: 5250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) NOTREACHED() << "Processing sync changes failed, unknown change type."; 5260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 5270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 5280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 5290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) content::NotificationService::current()->Notify( 5300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) chrome::NOTIFICATION_FOREIGN_SESSION_UPDATED, 5310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) content::Source<Profile>(profile_), 5320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) content::NotificationService::NoDetails()); 5334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return syncer::SyncError(); 5344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 5354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)syncer::SyncChange SessionsSyncManager::TombstoneTab( 5374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const sync_pb::SessionSpecifics& tab) { 5384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!tab.has_tab_node_id()) { 5394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) LOG(WARNING) << "Old sessions node without tab node id; can't tombstone."; 5404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return syncer::SyncChange(); 5414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 5424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return syncer::SyncChange( 5434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FROM_HERE, 5444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SyncChange::ACTION_DELETE, 5454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SyncData::CreateLocalDelete( 5460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch TabNodePool::TabIdToTag(current_machine_tag(), 5474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) tab.tab_node_id()), 5484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) syncer::SESSIONS)); 5494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 5504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 5514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool SessionsSyncManager::GetAllForeignSessions( 5534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::vector<const SyncedSession*>* sessions) { 5544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return session_tracker_.LookupAllForeignSessions(sessions); 5554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 5564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool SessionsSyncManager::InitFromSyncModel( 5584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const syncer::SyncDataList& sync_data, 5595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syncer::SyncDataList* restored_tabs, 5604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) syncer::SyncChangeList* new_changes) { 5614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool found_current_header = false; 5624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (syncer::SyncDataList::const_iterator it = sync_data.begin(); 5634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) it != sync_data.end(); 5644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ++it) { 5654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const syncer::SyncData& data = *it; 5664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(data.GetSpecifics().has_session()); 5674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const sync_pb::SessionSpecifics& specifics = data.GetSpecifics().session(); 5684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (specifics.session_tag().empty() || 5694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) (specifics.has_tab() && (!specifics.has_tab_node_id() || 5704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) !specifics.tab().has_tab_id()))) { 5714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) syncer::SyncChange tombstone(TombstoneTab(specifics)); 5724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (tombstone.IsValid()) 5734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) new_changes->push_back(tombstone); 5744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else if (specifics.session_tag() != current_machine_tag()) { 575e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch UpdateTrackerWithForeignSession( 576e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch specifics, syncer::SyncDataRemote(data).GetModifiedTime()); 5774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 5784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // This is previously stored local session information. 5794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (specifics.has_header() && !found_current_header) { 5804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // This is our previous header node, reuse it. 5814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) found_current_header = true; 5824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (specifics.header().has_client_name()) 5834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) current_session_name_ = specifics.header().client_name(); 5844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 5854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (specifics.has_header() || !specifics.has_tab()) { 5864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) LOG(WARNING) << "Found more than one session header node with local " 5874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) << "tag."; 5884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) syncer::SyncChange tombstone(TombstoneTab(specifics)); 5894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (tombstone.IsValid()) 5904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) new_changes->push_back(tombstone); 5914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 5924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // This is a valid old tab node, add it to the pool so it can be 5934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // reused for reassociation. 5944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) local_tab_pool_.AddTabNode(specifics.tab_node_id()); 5955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) restored_tabs->push_back(*it); 5964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 5974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 5984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 5994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return found_current_header; 6014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 6024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void SessionsSyncManager::UpdateTrackerWithForeignSession( 6044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const sync_pb::SessionSpecifics& specifics, 6054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const base::Time& modification_time) { 6064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string foreign_session_tag = specifics.session_tag(); 6074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK_NE(foreign_session_tag, current_machine_tag()); 6084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SyncedSession* foreign_session = 6104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_tracker_.GetSession(foreign_session_tag); 6114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (specifics.has_header()) { 6124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Read in the header data for this foreign session. 6134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Header data contains window information and ordered tab id's for each 6144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // window. 6154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 61603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (!IsValidSessionHeader(specifics.header())) { 61703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) LOG(WARNING) << "Ignoring foreign session node with invalid header " 61803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) << "and tag " << foreign_session_tag << "."; 61903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return; 62003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 62103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 6224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Load (or create) the SyncedSession object for this client. 6234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const sync_pb::SessionHeader& header = specifics.header(); 6244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) PopulateSessionHeaderFromSpecifics(header, 6254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) modification_time, 6264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) foreign_session); 6274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Reset the tab/window tracking for this session (must do this before 6294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // we start calling PutWindowInSession and PutTabInWindow so that all 6304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // unused tabs/windows get cleared by the CleanupSession(...) call). 6314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_tracker_.ResetSessionTracking(foreign_session_tag); 6324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Process all the windows and their tab information. 6344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int num_windows = header.window_size(); 6354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DVLOG(1) << "Associating " << foreign_session_tag << " with " 6364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) << num_windows << " windows."; 6374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (int i = 0; i < num_windows; ++i) { 6394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const sync_pb::SessionWindow& window_s = header.window(i); 6404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SessionID::id_type window_id = window_s.window_id(); 6414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_tracker_.PutWindowInSession(foreign_session_tag, 6424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) window_id); 6434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) BuildSyncedSessionFromSpecifics(foreign_session_tag, 6444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) window_s, 6454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) modification_time, 6464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) foreign_session->windows[window_id]); 6474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Delete any closed windows and unused tabs as necessary. 6494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_tracker_.CleanupSession(foreign_session_tag); 6504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else if (specifics.has_tab()) { 6514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const sync_pb::SessionTab& tab_s = specifics.tab(); 6524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SessionID::id_type tab_id = tab_s.tab_id(); 6534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SessionTab* tab = 6544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_tracker_.GetTab(foreign_session_tag, 6554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) tab_id, 6564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) specifics.tab_node_id()); 6574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Update SessionTab based on protobuf. 6594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) tab->SetFromSyncData(tab_s, modification_time); 6604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // If a favicon or favicon urls are present, load the URLs and visit 6624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // times into the in-memory favicon cache. 6634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) RefreshFaviconVisitTimesFromForeignTab(tab_s, modification_time); 6644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Update the last modified time. 6664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (foreign_session->modified_time < modification_time) 6674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) foreign_session->modified_time = modification_time; 6684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 6694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) LOG(WARNING) << "Ignoring foreign session node with missing header/tab " 6704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) << "fields and tag " << foreign_session_tag << "."; 6714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 6734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void SessionsSyncManager::InitializeCurrentMachineTag() { 6754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(current_machine_tag_.empty()); 6764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string persisted_guid; 677f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) persisted_guid = sync_prefs_.GetSyncSessionsGUID(); 6784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!persisted_guid.empty()) { 6794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) current_machine_tag_ = persisted_guid; 6804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DVLOG(1) << "Restoring persisted session sync guid: " << persisted_guid; 6814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 6825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(local_device_); 6835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::string cache_guid = local_device_->GetLocalSyncCacheGUID(); 6845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(!cache_guid.empty()); 6855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) current_machine_tag_ = BuildMachineTag(cache_guid); 6864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DVLOG(1) << "Creating session sync guid: " << current_machine_tag_; 687f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) sync_prefs_.SetSyncSessionsGUID(current_machine_tag_); 6884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) local_tab_pool_.SetMachineTag(current_machine_tag_); 6914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 6924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static 6944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void SessionsSyncManager::PopulateSessionHeaderFromSpecifics( 6954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const sync_pb::SessionHeader& header_specifics, 6964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Time mtime, 6974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SyncedSession* session_header) { 6984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (header_specifics.has_client_name()) 6994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_header->session_name = header_specifics.client_name(); 7004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (header_specifics.has_device_type()) { 7014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) switch (header_specifics.device_type()) { 7024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case sync_pb::SyncEnums_DeviceType_TYPE_WIN: 7034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_header->device_type = SyncedSession::TYPE_WIN; 7044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 7054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case sync_pb::SyncEnums_DeviceType_TYPE_MAC: 7064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_header->device_type = SyncedSession::TYPE_MACOSX; 7074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 7084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case sync_pb::SyncEnums_DeviceType_TYPE_LINUX: 7094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_header->device_type = SyncedSession::TYPE_LINUX; 7104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 7114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case sync_pb::SyncEnums_DeviceType_TYPE_CROS: 7124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_header->device_type = SyncedSession::TYPE_CHROMEOS; 7134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 7144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case sync_pb::SyncEnums_DeviceType_TYPE_PHONE: 7154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_header->device_type = SyncedSession::TYPE_PHONE; 7164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 7174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case sync_pb::SyncEnums_DeviceType_TYPE_TABLET: 7184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_header->device_type = SyncedSession::TYPE_TABLET; 7194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 7204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case sync_pb::SyncEnums_DeviceType_TYPE_OTHER: 7214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Intentionally fall-through 7224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) default: 7234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_header->device_type = SyncedSession::TYPE_OTHER; 7244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 7254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 7264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 7274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_header->modified_time = mtime; 7284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 7294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static 7314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void SessionsSyncManager::BuildSyncedSessionFromSpecifics( 7324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& session_tag, 7334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const sync_pb::SessionWindow& specifics, 7344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Time mtime, 7354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SessionWindow* session_window) { 7364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (specifics.has_window_id()) 7374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_window->window_id.set_id(specifics.window_id()); 7384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (specifics.has_selected_tab_index()) 7394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_window->selected_tab_index = specifics.selected_tab_index(); 7404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (specifics.has_browser_type()) { 7414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (specifics.browser_type() == 7424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sync_pb::SessionWindow_BrowserType_TYPE_TABBED) { 7434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_window->type = 1; 7444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 7454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_window->type = 2; 7464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 7474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 7484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_window->timestamp = mtime; 7494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_window->tabs.resize(specifics.tab_size(), NULL); 7504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (int i = 0; i < specifics.tab_size(); i++) { 7514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SessionID::id_type tab_id = specifics.tab(i); 7524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_tracker_.PutTabInWindow(session_tag, 7534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_window->window_id.id(), 7544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) tab_id, 7554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) i); 7564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 7574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 7584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void SessionsSyncManager::RefreshFaviconVisitTimesFromForeignTab( 7604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const sync_pb::SessionTab& tab, const base::Time& modification_time) { 7614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // First go through and iterate over all the navigations, checking if any 7624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // have valid favicon urls. 7634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (int i = 0; i < tab.navigation_size(); ++i) { 7644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!tab.navigation(i).favicon_url().empty()) { 7654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& page_url = tab.navigation(i).virtual_url(); 7664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& favicon_url = tab.navigation(i).favicon_url(); 7674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) favicon_cache_.OnReceivedSyncFavicon(GURL(page_url), 7684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) GURL(favicon_url), 7694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string(), 7704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) syncer::TimeToProtoTime( 7714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) modification_time)); 7724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 7734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 7744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 7754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool SessionsSyncManager::GetSyncedFaviconForPageURL( 7774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& page_url, 7784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_refptr<base::RefCountedMemory>* favicon_png) const { 7794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return favicon_cache_.GetSyncedFaviconForPageURL(GURL(page_url), favicon_png); 7804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 7814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 782f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SessionsSyncManager::DeleteForeignSession(const std::string& tag) { 783f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) syncer::SyncChangeList changes; 784f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DeleteForeignSessionInternal(tag, &changes); 785f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) sync_processor_->ProcessSyncChanges(FROM_HERE, changes); 786f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 787f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 788f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SessionsSyncManager::DeleteForeignSessionInternal( 7894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& tag, syncer::SyncChangeList* change_output) { 7904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (tag == current_machine_tag()) { 7914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) LOG(ERROR) << "Attempting to delete local session. This is not currently " 7924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) << "supported."; 7934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 7944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 7954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::set<int> tab_node_ids_to_delete; 7974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_tracker_.LookupTabNodeIds(tag, &tab_node_ids_to_delete); 7984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!DisassociateForeignSession(tag)) { 7994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // We don't have any data for this session, our work here is done! 8004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 8014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 8024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 8034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Prepare deletes for the meta-node as well as individual tab nodes. 8044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) change_output->push_back(syncer::SyncChange( 8054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FROM_HERE, 8064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SyncChange::ACTION_DELETE, 8074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SyncData::CreateLocalDelete(tag, syncer::SESSIONS))); 8084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 8094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (std::set<int>::const_iterator it = tab_node_ids_to_delete.begin(); 8104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) it != tab_node_ids_to_delete.end(); 8114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ++it) { 8124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) change_output->push_back(syncer::SyncChange( 8134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FROM_HERE, 8144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SyncChange::ACTION_DELETE, 8150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch SyncData::CreateLocalDelete(TabNodePool::TabIdToTag(tag, *it), 8164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) syncer::SESSIONS))); 8174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 818effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch content::NotificationService::current()->Notify( 819effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch chrome::NOTIFICATION_FOREIGN_SESSION_UPDATED, 820effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch content::Source<Profile>(profile_), 821effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch content::NotificationService::NoDetails()); 8224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 8234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 8244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool SessionsSyncManager::DisassociateForeignSession( 8254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& foreign_session_tag) { 8264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (foreign_session_tag == current_machine_tag()) { 8274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DVLOG(1) << "Local session deleted! Doing nothing until a navigation is " 8284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) << "triggered."; 8294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return false; 8304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 8314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DVLOG(1) << "Disassociating session " << foreign_session_tag; 8324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return session_tracker_.DeleteSession(foreign_session_tag); 8334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 8344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 8354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static 8364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)GURL SessionsSyncManager::GetCurrentVirtualURL( 8374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const SyncedTabDelegate& tab_delegate) { 8384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const int current_index = tab_delegate.GetCurrentEntryIndex(); 8394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const int pending_index = tab_delegate.GetPendingEntryIndex(); 8404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const NavigationEntry* current_entry = 8414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) (current_index == pending_index) ? 8424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) tab_delegate.GetPendingEntry() : 8434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) tab_delegate.GetEntryAtIndex(current_index); 8444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return current_entry->GetVirtualURL(); 8454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 8464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 8474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static 8484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)GURL SessionsSyncManager::GetCurrentFaviconURL( 8494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const SyncedTabDelegate& tab_delegate) { 8504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const int current_index = tab_delegate.GetCurrentEntryIndex(); 8514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const int pending_index = tab_delegate.GetPendingEntryIndex(); 8524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const NavigationEntry* current_entry = 8534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) (current_index == pending_index) ? 8544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) tab_delegate.GetPendingEntry() : 8554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) tab_delegate.GetEntryAtIndex(current_index); 8564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return (current_entry->GetFavicon().valid ? 8574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) current_entry->GetFavicon().url : 8584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) GURL()); 8594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 8604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 861f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool SessionsSyncManager::GetForeignSession( 862f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& tag, 863f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::vector<const SessionWindow*>* windows) { 864f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return session_tracker_.LookupSessionWindows(tag, windows); 865f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 866f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 867f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool SessionsSyncManager::GetForeignTab( 868f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& tag, 869f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const SessionID::id_type tab_id, 870f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const SessionTab** tab) { 871f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const SessionTab* synced_tab = NULL; 872f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool success = session_tracker_.LookupSessionTab(tag, 873f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) tab_id, 874f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &synced_tab); 875f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (success) 876f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *tab = synced_tab; 877f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return success; 878f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 879f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 8804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void SessionsSyncManager::LocalTabDelegateToSpecifics( 8814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const SyncedTabDelegate& tab_delegate, 8824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sync_pb::SessionSpecifics* specifics) { 8834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SessionTab* session_tab = NULL; 8844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_tab = 8854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_tracker_.GetTab(current_machine_tag(), 8864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) tab_delegate.GetSessionId(), 8874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) tab_delegate.GetSyncId()); 8884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SetSessionTabFromDelegate(tab_delegate, base::Time::Now(), session_tab); 8894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sync_pb::SessionTab tab_s = session_tab->ToSyncData(); 8904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) specifics->set_session_tag(current_machine_tag_); 8914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) specifics->set_tab_node_id(tab_delegate.GetSyncId()); 8924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) specifics->mutable_tab()->CopyFrom(tab_s); 8934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 8944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 8955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SessionsSyncManager::AssociateRestoredPlaceholderTab( 8964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const SyncedTabDelegate& tab_delegate, 8974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SessionID::id_type new_tab_id, 8985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const syncer::SyncDataList& restored_tabs, 8994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) syncer::SyncChangeList* change_output) { 9000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK_NE(tab_delegate.GetSyncId(), TabNodePool::kInvalidTabNodeID); 9015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Rewrite the tab using |restored_tabs| to retrieve the specifics. 9025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (restored_tabs.empty()) { 9035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DLOG(WARNING) << "Can't Update tab ID."; 9045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 9055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 9065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 9075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (syncer::SyncDataList::const_iterator it = restored_tabs.begin(); 9085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) it != restored_tabs.end(); 9095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ++it) { 9105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (it->GetSpecifics().session().tab_node_id() != 9115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) tab_delegate.GetSyncId()) { 9125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) continue; 9135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 9145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 9155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sync_pb::EntitySpecifics entity; 9165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sync_pb::SessionSpecifics* specifics = entity.mutable_session(); 9175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) specifics->CopyFrom(it->GetSpecifics().session()); 9185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(specifics->has_tab()); 9194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 9204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Update tab node pool with the new association. 9215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) local_tab_pool_.ReassociateTabNode(tab_delegate.GetSyncId(), 9225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new_tab_id); 9235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TabLink* tab_link = new TabLink(tab_delegate.GetSyncId(), 9245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &tab_delegate); 9255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) local_tab_map_[new_tab_id] = make_linked_ptr<TabLink>(tab_link); 9265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 9275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (specifics->tab().tab_id() == new_tab_id) 9285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 9295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 9305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The tab_id changed (e.g due to session restore), so update sync. 9315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) specifics->mutable_tab()->set_tab_id(new_tab_id); 9324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) syncer::SyncData data = syncer::SyncData::CreateLocalData( 9330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch TabNodePool::TabIdToTag(current_machine_tag_, 9345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) specifics->tab_node_id()), 9355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) current_session_name_, 9365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) entity); 9374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) change_output->push_back(syncer::SyncChange( 9384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FROM_HERE, syncer::SyncChange::ACTION_UPDATE, data)); 9395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 9404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 9414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 9424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 9434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static. 9444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void SessionsSyncManager::SetSessionTabFromDelegate( 9454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const SyncedTabDelegate& tab_delegate, 9464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Time mtime, 9474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SessionTab* session_tab) { 9484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(session_tab); 9494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_tab->window_id.set_id(tab_delegate.GetWindowId()); 9504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_tab->tab_id.set_id(tab_delegate.GetSessionId()); 9514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_tab->tab_visual_index = 0; 9526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Use -1 to indicate that the index hasn't been set properly yet. 9536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) session_tab->current_navigation_index = -1; 9544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_tab->pinned = tab_delegate.IsPinned(); 9554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_tab->extension_app_id = tab_delegate.GetExtensionAppId(); 9564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_tab->user_agent_override.clear(); 9574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_tab->timestamp = mtime; 9584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const int current_index = tab_delegate.GetCurrentEntryIndex(); 9594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const int pending_index = tab_delegate.GetPendingEntryIndex(); 9604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const int min_index = std::max(0, current_index - kMaxSyncNavigationCount); 9614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const int max_index = std::min(current_index + kMaxSyncNavigationCount, 9624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) tab_delegate.GetEntryCount()); 963f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool is_supervised = tab_delegate.ProfileIsSupervised(); 9644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_tab->navigations.clear(); 9654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 9664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (int i = min_index; i < max_index; ++i) { 9674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const NavigationEntry* entry = (i == pending_index) ? 9684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) tab_delegate.GetPendingEntry() : tab_delegate.GetEntryAtIndex(i); 9694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(entry); 9704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!entry->GetVirtualURL().is_valid()) 9714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) continue; 9724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 9736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Set current_navigation_index to the index in navigations. 9746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (i == current_index) 9756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) session_tab->current_navigation_index = session_tab->navigations.size(); 9766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 9774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_tab->navigations.push_back( 978cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SerializedNavigationEntry::FromNavigationEntry(i, *entry)); 979f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (is_supervised) { 9804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_tab->navigations.back().set_blocked_state( 9814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SerializedNavigationEntry::STATE_ALLOWED); 9824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 9834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 9844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 9856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // If the current navigation is invalid, set the index to the end of the 9866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // navigation array. 9876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (session_tab->current_navigation_index < 0) { 9886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) session_tab->current_navigation_index = 9896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) session_tab->navigations.size() - 1; 9906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 9916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 992f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (is_supervised) { 9934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::vector<const NavigationEntry*>& blocked_navigations = 9944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *tab_delegate.GetBlockedNavigations(); 9954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int offset = session_tab->navigations.size(); 9964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (size_t i = 0; i < blocked_navigations.size(); ++i) { 9974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_tab->navigations.push_back( 9984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SerializedNavigationEntry::FromNavigationEntry( 9994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) i + offset, *blocked_navigations[i])); 10004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_tab->navigations.back().set_blocked_state( 10014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SerializedNavigationEntry::STATE_BLOCKED); 10024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // TODO(bauerb): Add categories 10034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 10044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 10054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session_tab->session_storage_persistent_id.clear(); 10064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 10074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1008f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)FaviconCache* SessionsSyncManager::GetFaviconCache() { 1009f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return &favicon_cache_; 1010f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 1011f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 10125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)SyncedWindowDelegatesGetter* 10135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)SessionsSyncManager::GetSyncedWindowDelegatesGetter() const { 10145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return synced_window_getter_.get(); 10155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 10165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1017a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void SessionsSyncManager::DoGarbageCollection() { 1018a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::vector<const SyncedSession*> sessions; 1019a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!GetAllForeignSessions(&sessions)) 1020a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; // No foreign sessions. 1021a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1022a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Iterate through all the sessions and delete any with age older than 1023a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // |stale_session_threshold_days_|. 1024a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) syncer::SyncChangeList changes; 1025a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (std::vector<const SyncedSession*>::const_iterator iter = 1026a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) sessions.begin(); iter != sessions.end(); ++iter) { 1027a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const SyncedSession* session = *iter; 1028a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int session_age_in_days = 1029a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) (base::Time::Now() - session->modified_time).InDays(); 1030a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::string session_tag = session->session_tag; 1031a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (session_age_in_days > 0 && // If false, local clock is not trustworty. 1032a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) static_cast<size_t>(session_age_in_days) > 1033a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) stale_session_threshold_days_) { 1034a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DVLOG(1) << "Found stale session " << session_tag 1035a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) << " with age " << session_age_in_days << ", deleting."; 1036a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DeleteForeignSessionInternal(session_tag, &changes); 1037a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 1038a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 1039a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1040a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!changes.empty()) 1041a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) sync_processor_->ProcessSyncChanges(FROM_HERE, changes); 1042a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 1043a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 10444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}; // namespace browser_sync 1045