OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/sync/glue/session_model_associator.h" | 5 #include "chrome/browser/sync/glue/session_model_associator.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <set> | 8 #include <set> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
209 for (std::vector<SyncedTabDelegate*>::const_iterator i = tabs.begin(); | 209 for (std::vector<SyncedTabDelegate*>::const_iterator i = tabs.begin(); |
210 i != tabs.end(); | 210 i != tabs.end(); |
211 ++i) { | 211 ++i) { |
212 ReassociateTab(**i); | 212 ReassociateTab(**i); |
213 } | 213 } |
214 if (waiting_for_change_) QuitLoopForTest(); | 214 if (waiting_for_change_) QuitLoopForTest(); |
215 } | 215 } |
216 | 216 |
217 void SessionModelAssociator::ReassociateTab(const SyncedTabDelegate& tab) { | 217 void SessionModelAssociator::ReassociateTab(const SyncedTabDelegate& tab) { |
218 DCHECK(CalledOnValidThread()); | 218 DCHECK(CalledOnValidThread()); |
219 if (!IsValidTab(tab)) | |
220 return; | |
221 | |
222 int64 sync_id; | 219 int64 sync_id; |
223 SessionID::id_type id = tab.GetSessionId(); | 220 SessionID::id_type id = tab.GetSessionId(); |
224 if (tab.IsBeingDestroyed()) { | 221 if (tab.IsBeingDestroyed()) { |
225 // This tab is closing. | 222 // This tab is closing. |
226 TabLinksMap::iterator tab_iter = tab_map_.find(id); | 223 TabLinksMap::iterator tab_iter = tab_map_.find(id); |
227 if (tab_iter == tab_map_.end()) { | 224 if (tab_iter == tab_map_.end()) { |
228 // We aren't tracking this tab (for example, sync setting page). | 225 // We aren't tracking this tab (for example, sync setting page). |
229 return; | 226 return; |
230 } | 227 } |
231 tab_pool_.FreeTabNode(tab_iter->second.sync_id()); | 228 tab_pool_.FreeTabNode(tab_iter->second.sync_id()); |
232 tab_map_.erase(tab_iter); | 229 tab_map_.erase(tab_iter); |
233 return; | 230 return; |
234 } | 231 } |
235 | 232 |
233 if (!IsValidTab(tab)) | |
234 return; | |
235 | |
236 TabLinksMap::const_iterator tablink = tab_map_.find(id); | 236 TabLinksMap::const_iterator tablink = tab_map_.find(id); |
237 if (tablink == tab_map_.end()) { | 237 if (tablink == tab_map_.end()) { |
238 // This is a new tab, get a sync node for it. | 238 // This is a new tab, get a sync node for it. |
239 sync_id = tab_pool_.GetFreeTabNode(); | 239 sync_id = tab_pool_.GetFreeTabNode(); |
240 if (sync_id == -1) { | |
tim (not reviewing)
2011/08/25 20:25:01
isn't there a constant for this -1 id?
also you se
Nicolas Zea
2011/08/25 20:52:01
Done.
| |
241 return; | |
tim (not reviewing)
2011/08/25 20:25:01
log something, perhaps?
Nicolas Zea
2011/08/25 20:52:01
Logging is done in the GetFreeTabNode call
| |
242 } | |
240 } else { | 243 } else { |
241 // This tab is already associated with a sync node, reuse it. | 244 // This tab is already associated with a sync node, reuse it. |
242 sync_id = tablink->second.sync_id(); | 245 sync_id = tablink->second.sync_id(); |
243 } | 246 } |
244 Associate(&tab, sync_id); | 247 Associate(&tab, sync_id); |
245 } | 248 } |
246 | 249 |
247 void SessionModelAssociator::Associate(const SyncedTabDelegate* tab, | 250 void SessionModelAssociator::Associate(const SyncedTabDelegate* tab, |
248 int64 sync_id) { | 251 int64 sync_id) { |
249 DCHECK(CalledOnValidThread()); | 252 DCHECK(CalledOnValidThread()); |
250 SessionID::id_type session_id = tab->GetSessionId(); | 253 SessionID::id_type session_id = tab->GetSessionId(); |
251 const SyncedWindowDelegate* window = | 254 const SyncedWindowDelegate* window = |
252 SyncedWindowDelegate::FindSyncedWindowDelegateWithId( | 255 SyncedWindowDelegate::FindSyncedWindowDelegateWithId( |
253 tab->GetWindowId()); | 256 tab->GetWindowId()); |
254 if (!window) { // Can happen for weird things like developer console. | 257 DCHECK(window); |
255 tab_pool_.FreeTabNode(sync_id); | |
256 return; | |
257 } | |
258 | 258 |
259 TabLinks t(sync_id, tab); | 259 TabLinks t(sync_id, tab); |
260 tab_map_[session_id] = t; | 260 tab_map_[session_id] = t; |
261 | 261 |
262 sync_api::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare()); | 262 sync_api::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare()); |
263 WriteTabContentsToSyncModel(*window, *tab, sync_id, &trans); | 263 WriteTabContentsToSyncModel(*window, *tab, sync_id, &trans); |
264 } | 264 } |
265 | 265 |
266 bool SessionModelAssociator::WriteTabContentsToSyncModel( | 266 bool SessionModelAssociator::WriteTabContentsToSyncModel( |
267 const SyncedWindowDelegate& window, | 267 const SyncedWindowDelegate& window, |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
424 sync_api::ReadNode root(&trans); | 424 sync_api::ReadNode root(&trans); |
425 if (!root.InitByTagLookup(kSessionsTag)) { | 425 if (!root.InitByTagLookup(kSessionsTag)) { |
426 error->Reset(FROM_HERE, kNoSessionsFolderError, model_type()); | 426 error->Reset(FROM_HERE, kNoSessionsFolderError, model_type()); |
427 return false; | 427 return false; |
428 } | 428 } |
429 | 429 |
430 // Make sure we have a machine tag. | 430 // Make sure we have a machine tag. |
431 if (current_machine_tag_.empty()) | 431 if (current_machine_tag_.empty()) |
432 InitializeCurrentMachineTag(&trans); | 432 InitializeCurrentMachineTag(&trans); |
433 synced_session_tracker_.SetLocalSessionTag(current_machine_tag_); | 433 synced_session_tracker_.SetLocalSessionTag(current_machine_tag_); |
434 UpdateAssociationsFromSyncModel(root, &trans); | 434 if (!UpdateAssociationsFromSyncModel(root, &trans)) { |
435 error->Reset(FROM_HERE, | |
436 "Failed to update associations from sync", | |
437 model_type()); | |
438 return false; | |
439 } | |
435 | 440 |
436 if (local_session_syncid_ == sync_api::kInvalidId) { | 441 if (local_session_syncid_ == sync_api::kInvalidId) { |
437 // The sync db didn't have a header node for us, we need to create one. | 442 // The sync db didn't have a header node for us, we need to create one. |
438 sync_api::WriteNode write_node(&trans); | 443 sync_api::WriteNode write_node(&trans); |
439 if (!write_node.InitUniqueByCreation(syncable::SESSIONS, root, | 444 if (!write_node.InitUniqueByCreation(syncable::SESSIONS, root, |
440 current_machine_tag_)) { | 445 current_machine_tag_)) { |
441 error->Reset(FROM_HERE, | 446 error->Reset(FROM_HERE, |
442 "Failed to create sessions header sync node.", | 447 "Failed to create sessions header sync node.", |
443 model_type()); | 448 model_type()); |
444 return false; | 449 return false; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
506 const sync_pb::SessionSpecifics& specifics = | 511 const sync_pb::SessionSpecifics& specifics = |
507 sync_node.GetSessionSpecifics(); | 512 sync_node.GetSessionSpecifics(); |
508 const int64 modification_time = sync_node.GetModificationTime(); | 513 const int64 modification_time = sync_node.GetModificationTime(); |
509 if (specifics.session_tag() != GetCurrentMachineTag()) { | 514 if (specifics.session_tag() != GetCurrentMachineTag()) { |
510 if (!AssociateForeignSpecifics(specifics, modification_time)) { | 515 if (!AssociateForeignSpecifics(specifics, modification_time)) { |
511 return false; | 516 return false; |
512 } | 517 } |
513 } else if (id != local_session_syncid_) { | 518 } else if (id != local_session_syncid_) { |
514 // This is previously stored local session information. | 519 // This is previously stored local session information. |
515 if (specifics.has_header()) { | 520 if (specifics.has_header()) { |
516 DCHECK_EQ(sync_api::kInvalidId, local_session_syncid_); | 521 if (sync_api::kInvalidId != local_session_syncid_) |
522 return false; | |
517 | 523 |
518 // This is our previous header node, reuse it. | 524 // This is our previous header node, reuse it. |
519 local_session_syncid_ = id; | 525 local_session_syncid_ = id; |
520 } else { | 526 } else { |
521 DCHECK(specifics.has_tab()); | 527 if (!specifics.has_tab()) |
528 return false; | |
522 | 529 |
523 // This is a tab node. We want to track these to reuse them in our free | 530 // This is a tab node. We want to track these to reuse them in our free |
524 // tab node pool. They will be overwritten eventually, so need to do | 531 // tab node pool. They will be overwritten eventually, so need to do |
525 // anything else. | 532 // anything else. |
526 tab_pool_.AddTabNode(id); | 533 tab_pool_.AddTabNode(id); |
527 } | 534 } |
528 } | 535 } |
529 | 536 |
530 id = sync_node.GetSuccessorId(); | 537 id = sync_node.GetSuccessorId(); |
531 } | 538 } |
532 | 539 |
533 // After updating from sync model all tabid's should be free. | 540 // After updating from sync model all tabid's should be free. |
534 DCHECK(tab_pool_.full()); | 541 if (!tab_pool_.full()) |
542 return false; | |
535 | 543 |
536 return true; | 544 return true; |
537 } | 545 } |
538 | 546 |
539 bool SessionModelAssociator::AssociateForeignSpecifics( | 547 bool SessionModelAssociator::AssociateForeignSpecifics( |
540 const sync_pb::SessionSpecifics& specifics, | 548 const sync_pb::SessionSpecifics& specifics, |
541 const int64 modification_time) { | 549 const int64 modification_time) { |
542 DCHECK(CalledOnValidThread()); | 550 DCHECK(CalledOnValidThread()); |
543 std::string foreign_session_tag = specifics.session_tag(); | 551 std::string foreign_session_tag = specifics.session_tag(); |
544 DCHECK(foreign_session_tag != GetCurrentMachineTag() || setup_for_test_); | 552 if (foreign_session_tag == GetCurrentMachineTag() && !setup_for_test_) |
553 return false; | |
545 | 554 |
546 if (specifics.has_header()) { | 555 if (specifics.has_header()) { |
547 // Read in the header data for this foreign session. | 556 // Read in the header data for this foreign session. |
548 // Header data contains window information and ordered tab id's for each | 557 // Header data contains window information and ordered tab id's for each |
549 // window. | 558 // window. |
550 | 559 |
551 // Load (or create) the SyncedSession object for this client. | 560 // Load (or create) the SyncedSession object for this client. |
552 SyncedSession* foreign_session = | 561 SyncedSession* foreign_session = |
553 synced_session_tracker_.GetSession(foreign_session_tag); | 562 synced_session_tracker_.GetSession(foreign_session_tag); |
554 | 563 |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
761 } | 770 } |
762 | 771 |
763 int64 SessionModelAssociator::TabNodePool::GetFreeTabNode() { | 772 int64 SessionModelAssociator::TabNodePool::GetFreeTabNode() { |
764 DCHECK_GT(machine_tag_.length(), 0U); | 773 DCHECK_GT(machine_tag_.length(), 0U); |
765 if (tab_pool_fp_ == -1) { | 774 if (tab_pool_fp_ == -1) { |
766 // Tab pool has no free nodes, allocate new one. | 775 // Tab pool has no free nodes, allocate new one. |
767 sync_api::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare()); | 776 sync_api::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare()); |
768 sync_api::ReadNode root(&trans); | 777 sync_api::ReadNode root(&trans); |
769 if (!root.InitByTagLookup(kSessionsTag)) { | 778 if (!root.InitByTagLookup(kSessionsTag)) { |
770 LOG(ERROR) << kNoSessionsFolderError; | 779 LOG(ERROR) << kNoSessionsFolderError; |
771 return 0; | 780 return -1; |
772 } | 781 } |
773 size_t tab_node_id = tab_syncid_pool_.size(); | 782 size_t tab_node_id = tab_syncid_pool_.size(); |
774 std::string tab_node_tag = TabIdToTag(machine_tag_, tab_node_id); | 783 std::string tab_node_tag = TabIdToTag(machine_tag_, tab_node_id); |
775 sync_api::WriteNode tab_node(&trans); | 784 sync_api::WriteNode tab_node(&trans); |
776 if (!tab_node.InitUniqueByCreation(syncable::SESSIONS, root, | 785 if (!tab_node.InitUniqueByCreation(syncable::SESSIONS, root, |
777 tab_node_tag)) { | 786 tab_node_tag)) { |
778 LOG(ERROR) << "Could not create new node!"; | 787 LOG(ERROR) << "Could not create new node with tag " |
788 << tab_node_tag << "!"; | |
779 return -1; | 789 return -1; |
780 } | 790 } |
781 tab_node.SetTitle(UTF8ToWide(tab_node_tag)); | 791 tab_node.SetTitle(UTF8ToWide(tab_node_tag)); |
782 | 792 |
783 // Grow the pool by 1 since we created a new node. We don't actually need | 793 // Grow the pool by 1 since we created a new node. We don't actually need |
784 // to put the node's id in the pool now, since the pool is still empty. | 794 // to put the node's id in the pool now, since the pool is still empty. |
785 // The id will be added when that tab is closed and the node is freed. | 795 // The id will be added when that tab is closed and the node is freed. |
786 tab_syncid_pool_.resize(tab_node_id + 1); | 796 tab_syncid_pool_.resize(tab_node_id + 1); |
787 VLOG(1) << "Adding sync node " << tab_node.GetId() << " to tab syncid pool"; | 797 VLOG(1) << "Adding sync node " << tab_node.GetId() << " to tab syncid pool"; |
788 return tab_node.GetId(); | 798 return tab_node.GetId(); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
841 } | 851 } |
842 if (num_populated == 0) | 852 if (num_populated == 0) |
843 return true; | 853 return true; |
844 return false; | 854 return false; |
845 } | 855 } |
846 | 856 |
847 // Valid local tab? | 857 // Valid local tab? |
848 bool SessionModelAssociator::IsValidTab(const SyncedTabDelegate& tab) { | 858 bool SessionModelAssociator::IsValidTab(const SyncedTabDelegate& tab) { |
849 DCHECK(CalledOnValidThread()); | 859 DCHECK(CalledOnValidThread()); |
850 if ((tab.profile() == sync_service_->profile() || | 860 if ((tab.profile() == sync_service_->profile() || |
851 sync_service_->profile() == NULL)) { | 861 sync_service_->profile() == NULL)) { // For tests. |
862 const SyncedWindowDelegate* window = | |
863 SyncedWindowDelegate::FindSyncedWindowDelegateWithId( | |
864 tab.GetWindowId()); | |
865 if (!window) | |
866 return false; | |
852 const NavigationEntry* entry = tab.GetActiveEntry(); | 867 const NavigationEntry* entry = tab.GetActiveEntry(); |
853 if (!entry) | 868 if (!entry) |
854 return false; | 869 return false; |
855 if (entry->virtual_url().is_valid() && | 870 if (entry->virtual_url().is_valid() && |
856 (entry->virtual_url() != GURL(chrome::kChromeUINewTabURL) || | 871 (entry->virtual_url() != GURL(chrome::kChromeUINewTabURL) || |
857 tab.GetEntryCount() > 1)) { | 872 tab.GetEntryCount() > 1)) { |
858 return true; | 873 return true; |
859 } | 874 } |
860 } | 875 } |
861 return false; | 876 return false; |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1056 bool SessionModelAssociator::CryptoReadyIfNecessary() { | 1071 bool SessionModelAssociator::CryptoReadyIfNecessary() { |
1057 // We only access the cryptographer while holding a transaction. | 1072 // We only access the cryptographer while holding a transaction. |
1058 sync_api::ReadTransaction trans(FROM_HERE, sync_service_->GetUserShare()); | 1073 sync_api::ReadTransaction trans(FROM_HERE, sync_service_->GetUserShare()); |
1059 syncable::ModelTypeSet encrypted_types; | 1074 syncable::ModelTypeSet encrypted_types; |
1060 encrypted_types = sync_api::GetEncryptedTypes(&trans); | 1075 encrypted_types = sync_api::GetEncryptedTypes(&trans); |
1061 return encrypted_types.count(syncable::SESSIONS) == 0 || | 1076 return encrypted_types.count(syncable::SESSIONS) == 0 || |
1062 sync_service_->IsCryptographerReady(&trans); | 1077 sync_service_->IsCryptographerReady(&trans); |
1063 } | 1078 } |
1064 | 1079 |
1065 } // namespace browser_sync | 1080 } // namespace browser_sync |
OLD | NEW |