Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/sync/sessions2/sessions_sync_manager.h" | 5 #include "chrome/browser/sync/sessions2/sessions_sync_manager.h" |
| 6 | 6 |
| 7 #include "chrome/browser/chrome_notification_types.h" | 7 #include "chrome/browser/chrome_notification_types.h" |
| 8 #if !defined(OS_ANDROID) | 8 #if !defined(OS_ANDROID) |
| 9 #include "chrome/browser/network_time/navigation_time_helper.h" | 9 #include "chrome/browser/network_time/navigation_time_helper.h" |
| 10 #endif | 10 #endif |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 30 | 30 |
| 31 namespace browser_sync { | 31 namespace browser_sync { |
| 32 | 32 |
| 33 // Maximum number of favicons to sync. | 33 // Maximum number of favicons to sync. |
| 34 // TODO(zea): pull this from the server. | 34 // TODO(zea): pull this from the server. |
| 35 static const int kMaxSyncFavicons = 200; | 35 static const int kMaxSyncFavicons = 200; |
| 36 | 36 |
| 37 // The maximum number of navigations in each direction we care to sync. | 37 // The maximum number of navigations in each direction we care to sync. |
| 38 static const int kMaxSyncNavigationCount = 6; | 38 static const int kMaxSyncNavigationCount = 6; |
| 39 | 39 |
| 40 // The URL at which the set of synced tabs is displayed. We treat it differently | |
| 41 // from all other URL's as accessing it triggers a sync refresh of Sessions. | |
| 42 static const char kNTPOpenTabSyncURL[] = "chrome://newtab/#open_tabs"; | |
| 43 | |
| 40 SessionsSyncManager::SessionsSyncManager( | 44 SessionsSyncManager::SessionsSyncManager( |
| 41 Profile* profile, | 45 Profile* profile, |
| 42 SyncInternalApiDelegate* delegate) | 46 SyncInternalApiDelegate* delegate, |
| 47 scoped_ptr<LocalEventRouter> router) | |
| 43 : favicon_cache_(profile, kMaxSyncFavicons), | 48 : favicon_cache_(profile, kMaxSyncFavicons), |
| 44 sync_prefs_(profile->GetPrefs()), | 49 sync_prefs_(profile->GetPrefs()), |
| 45 profile_(profile), | 50 profile_(profile), |
| 46 delegate_(delegate), | 51 delegate_(delegate), |
| 47 local_session_header_node_id_(TabNodePool2::kInvalidTabNodeID) { | 52 local_session_header_node_id_(TabNodePool2::kInvalidTabNodeID), |
| 53 local_event_router_(router.Pass()) { | |
| 48 } | 54 } |
| 49 | 55 |
| 50 SessionsSyncManager::~SessionsSyncManager() { | 56 SessionsSyncManager::~SessionsSyncManager() { |
| 51 } | 57 } |
| 52 | 58 |
| 53 // Returns the GUID-based string that should be used for | 59 // Returns the GUID-based string that should be used for |
| 54 // |SessionsSyncManager::current_machine_tag_|. | 60 // |SessionsSyncManager::current_machine_tag_|. |
| 55 static std::string BuildMachineTag(const std::string& cache_guid) { | 61 static std::string BuildMachineTag(const std::string& cache_guid) { |
| 56 std::string machine_tag = "session_sync"; | 62 std::string machine_tag = "session_sync"; |
| 57 machine_tag.append(cache_guid); | 63 machine_tag.append(cache_guid); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 109 delegate_->GetLocalSyncCacheGUID())); | 115 delegate_->GetLocalSyncCacheGUID())); |
| 110 if (current_machine_tag_.compare(sync_machine_tag) != 0) | 116 if (current_machine_tag_.compare(sync_machine_tag) != 0) |
| 111 DeleteForeignSessionInternal(sync_machine_tag, &new_changes); | 117 DeleteForeignSessionInternal(sync_machine_tag, &new_changes); |
| 112 #endif | 118 #endif |
| 113 | 119 |
| 114 // Check if anything has changed on the local client side. | 120 // Check if anything has changed on the local client side. |
| 115 AssociateWindows(RELOAD_TABS, &new_changes); | 121 AssociateWindows(RELOAD_TABS, &new_changes); |
| 116 | 122 |
| 117 merge_result.set_error( | 123 merge_result.set_error( |
| 118 sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes)); | 124 sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes)); |
| 125 | |
| 126 local_event_router_->StartRoutingTo(this); | |
| 119 return merge_result; | 127 return merge_result; |
| 120 } | 128 } |
| 121 | 129 |
| 122 void SessionsSyncManager::AssociateWindows( | 130 void SessionsSyncManager::AssociateWindows( |
| 123 ReloadTabsOption option, | 131 ReloadTabsOption option, |
| 124 syncer::SyncChangeList* change_output) { | 132 syncer::SyncChangeList* change_output) { |
| 125 const std::string local_tag = current_machine_tag(); | 133 const std::string local_tag = current_machine_tag(); |
| 126 sync_pb::SessionSpecifics specifics; | 134 sync_pb::SessionSpecifics specifics; |
| 127 specifics.set_session_tag(local_tag); | 135 specifics.set_session_tag(local_tag); |
| 128 sync_pb::SessionHeader* header_s = specifics.mutable_header(); | 136 sync_pb::SessionHeader* header_s = specifics.mutable_header(); |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 286 const GURL new_url = GetCurrentVirtualURL(*tab); | 294 const GURL new_url = GetCurrentVirtualURL(*tab); |
| 287 if (new_url != tab_link->url()) { | 295 if (new_url != tab_link->url()) { |
| 288 tab_link->set_url(new_url); | 296 tab_link->set_url(new_url); |
| 289 favicon_cache_.OnFaviconVisited(new_url, GetCurrentFaviconURL(*tab)); | 297 favicon_cache_.OnFaviconVisited(new_url, GetCurrentFaviconURL(*tab)); |
| 290 } | 298 } |
| 291 | 299 |
| 292 session_tracker_.GetSession(current_machine_tag())->modified_time = | 300 session_tracker_.GetSession(current_machine_tag())->modified_time = |
| 293 base::Time::Now(); | 301 base::Time::Now(); |
| 294 } | 302 } |
| 295 | 303 |
| 296 void SessionsSyncManager::OnLocalTabModified( | 304 void SessionsSyncManager::OnLocalTabModified(SyncedTabDelegate* modified_tab) { |
| 297 const SyncedTabDelegate& modified_tab, syncer::SyncError* error) { | 305 const content::NavigationEntry* entry = modified_tab->GetActiveEntry(); |
| 298 NOTIMPLEMENTED() << "TODO(tim): SessionModelAssociator::Observe equivalent."; | 306 if (!modified_tab->IsBeingDestroyed() && |
| 307 entry && | |
| 308 entry->GetVirtualURL().is_valid() && | |
| 309 entry->GetVirtualURL().spec() == kNTPOpenTabSyncURL) { | |
| 310 DVLOG(1) << "Triggering sync refresh for sessions datatype."; | |
| 311 const syncer::ModelTypeSet types(syncer::SESSIONS); | |
| 312 content::NotificationService::current()->Notify( | |
|
rlarocque
2013/11/27 22:47:51
I've always thought that this would be better impl
tim (not reviewing)
2013/12/02 18:29:49
That does seem nice. I actually wrestled around wi
rlarocque
2013/12/02 18:53:53
By "not requiring sessions to be enabled", I mean
| |
| 313 chrome::NOTIFICATION_SYNC_REFRESH_LOCAL, | |
| 314 content::Source<Profile>(profile_), | |
| 315 content::Details<const syncer::ModelTypeSet>(&types)); | |
| 316 } | |
| 317 | |
| 318 syncer::SyncChangeList changes; | |
| 319 // Associate tabs first so the synced session tracker is aware of them. | |
| 320 AssociateTab(modified_tab, &changes); | |
| 321 // Note, we always associate windows because it's possible a tab became | |
| 322 // "interesting" by going to a valid URL, in which case it needs to be added | |
| 323 // to the window's tab information. | |
| 324 AssociateWindows(DONT_RELOAD_TABS, &changes); | |
| 325 sync_processor_->ProcessSyncChanges(FROM_HERE, changes); | |
| 299 } | 326 } |
| 300 | 327 |
| 301 void SessionsSyncManager::OnBrowserOpened() { | 328 void SessionsSyncManager::OnFaviconPageUrlsUpdated( |
| 302 NOTIMPLEMENTED() << "TODO(tim): SessionModelAssociator::Observe equivalent."; | 329 const std::set<GURL>& updated_favicon_page_urls) { |
| 330 // TODO(zea): consider a separate container for tabs with outstanding favicon | |
| 331 // loads so we don't have to iterate through all tabs comparing urls. | |
| 332 for (std::set<GURL>::const_iterator i = updated_favicon_page_urls.begin(); | |
| 333 i != updated_favicon_page_urls.end(); ++i) { | |
| 334 for (TabLinksMap::iterator tab_iter = local_tab_map_.begin(); | |
| 335 tab_iter != local_tab_map_.end(); | |
| 336 ++tab_iter) { | |
| 337 if (tab_iter->second->url() == *i) | |
| 338 favicon_cache_.OnPageFaviconUpdated(*i); | |
| 339 } | |
| 340 } | |
| 303 } | 341 } |
| 304 | 342 |
| 305 bool SessionsSyncManager::ShouldSyncTab(const SyncedTabDelegate& tab) const { | 343 bool SessionsSyncManager::ShouldSyncTab(const SyncedTabDelegate& tab) const { |
| 306 if (tab.profile() != profile_) | 344 if (tab.profile() != profile_) |
| 307 return false; | 345 return false; |
| 308 | 346 |
| 309 if (SyncedWindowDelegate::FindSyncedWindowDelegateWithId( | 347 if (SyncedWindowDelegate::FindSyncedWindowDelegateWithId( |
| 310 tab.GetWindowId()) == NULL) { | 348 tab.GetWindowId()) == NULL) { |
| 311 return false; | 349 return false; |
| 312 } | 350 } |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 338 } | 376 } |
| 339 | 377 |
| 340 // static. | 378 // static. |
| 341 bool SessionsSyncManager::ShouldSyncWindow( | 379 bool SessionsSyncManager::ShouldSyncWindow( |
| 342 const SyncedWindowDelegate* window) { | 380 const SyncedWindowDelegate* window) { |
| 343 if (window->IsApp()) | 381 if (window->IsApp()) |
| 344 return false; | 382 return false; |
| 345 return window->IsTypeTabbed() || window->IsTypePopup(); | 383 return window->IsTypeTabbed() || window->IsTypePopup(); |
| 346 } | 384 } |
| 347 | 385 |
| 348 void SessionsSyncManager::ForwardRelevantFaviconUpdatesToFaviconCache( | |
| 349 const std::set<GURL>& updated_favicon_page_urls) { | |
| 350 // TODO(zea): consider a separate container for tabs with outstanding favicon | |
| 351 // loads so we don't have to iterate through all tabs comparing urls. | |
| 352 for (std::set<GURL>::const_iterator i = updated_favicon_page_urls.begin(); | |
| 353 i != updated_favicon_page_urls.end(); ++i) { | |
| 354 for (TabLinksMap::iterator tab_iter = local_tab_map_.begin(); | |
| 355 tab_iter != local_tab_map_.end(); | |
| 356 ++tab_iter) { | |
| 357 if (tab_iter->second->url() == *i) | |
| 358 favicon_cache_.OnPageFaviconUpdated(*i); | |
| 359 } | |
| 360 } | |
| 361 } | |
| 362 | |
| 363 void SessionsSyncManager::StopSyncing(syncer::ModelType type) { | 386 void SessionsSyncManager::StopSyncing(syncer::ModelType type) { |
| 364 NOTIMPLEMENTED(); | 387 NOTIMPLEMENTED(); |
| 365 } | 388 } |
| 366 | 389 |
| 367 syncer::SyncDataList SessionsSyncManager::GetAllSyncData( | 390 syncer::SyncDataList SessionsSyncManager::GetAllSyncData( |
| 368 syncer::ModelType type) const { | 391 syncer::ModelType type) const { |
| 369 NOTIMPLEMENTED(); | 392 NOTIMPLEMENTED(); |
| 370 return syncer::SyncDataList(); | 393 return syncer::SyncDataList(); |
| 371 } | 394 } |
| 372 | 395 |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 389 it->sync_data().GetSpecifics().session(); | 412 it->sync_data().GetSpecifics().session(); |
| 390 switch (it->change_type()) { | 413 switch (it->change_type()) { |
| 391 case syncer::SyncChange::ACTION_DELETE: | 414 case syncer::SyncChange::ACTION_DELETE: |
| 392 // Deletions are all or nothing (since we only ever delete entire | 415 // Deletions are all or nothing (since we only ever delete entire |
| 393 // sessions). Therefore we don't care if it's a tab node or meta node, | 416 // sessions). Therefore we don't care if it's a tab node or meta node, |
| 394 // and just ensure we've disassociated. | 417 // and just ensure we've disassociated. |
| 395 if (current_machine_tag() == session.session_tag()) { | 418 if (current_machine_tag() == session.session_tag()) { |
| 396 // Another client has attempted to delete our local data (possibly by | 419 // Another client has attempted to delete our local data (possibly by |
| 397 // error or a clock is inaccurate). Just ignore the deletion for now | 420 // error or a clock is inaccurate). Just ignore the deletion for now |
| 398 // to avoid any possible ping-pong delete/reassociate sequence. | 421 // to avoid any possible ping-pong delete/reassociate sequence. |
| 422 // TODO(tim): Bug 98892. This corrupts TabNodePool. Perform full | |
| 423 // re-association. | |
| 399 LOG(WARNING) << "Local session data deleted. Ignoring until next " | 424 LOG(WARNING) << "Local session data deleted. Ignoring until next " |
| 400 << "local navigation event."; | 425 << "local navigation event."; |
| 401 } else if (session.has_header()) { | 426 } else if (session.has_header()) { |
| 402 // Disassociate only when header node is deleted. For tab node | 427 // Disassociate only when header node is deleted. For tab node |
| 403 // deletions, the header node will be updated and foreign tab will | 428 // deletions, the header node will be updated and foreign tab will |
| 404 // get deleted. | 429 // get deleted. |
| 405 DisassociateForeignSession(session.session_tag()); | 430 DisassociateForeignSession(session.session_tag()); |
| 406 } | 431 } |
| 407 continue; | 432 continue; |
| 408 case syncer::SyncChange::ACTION_ADD: | 433 case syncer::SyncChange::ACTION_ADD: |
| (...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 861 SerializedNavigationEntry::FromNavigationEntry( | 886 SerializedNavigationEntry::FromNavigationEntry( |
| 862 i + offset, *blocked_navigations[i])); | 887 i + offset, *blocked_navigations[i])); |
| 863 session_tab->navigations.back().set_blocked_state( | 888 session_tab->navigations.back().set_blocked_state( |
| 864 SerializedNavigationEntry::STATE_BLOCKED); | 889 SerializedNavigationEntry::STATE_BLOCKED); |
| 865 // TODO(bauerb): Add categories | 890 // TODO(bauerb): Add categories |
| 866 } | 891 } |
| 867 } | 892 } |
| 868 session_tab->session_storage_persistent_id.clear(); | 893 session_tab->session_storage_persistent_id.clear(); |
| 869 } | 894 } |
| 870 | 895 |
| 871 | |
| 872 FaviconCache* SessionsSyncManager::GetFaviconCache() { | 896 FaviconCache* SessionsSyncManager::GetFaviconCache() { |
| 873 return &favicon_cache_; | 897 return &favicon_cache_; |
| 874 } | 898 } |
| 875 | 899 |
| 876 }; // namespace browser_sync | 900 }; // namespace browser_sync |
| OLD | NEW |