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 |