| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 18 matching lines...) Expand all Loading... |
| 29 #include "chrome/common/chrome_notification_types.h" | 29 #include "chrome/common/chrome_notification_types.h" |
| 30 #include "chrome/common/chrome_switches.h" | 30 #include "chrome/common/chrome_switches.h" |
| 31 #include "chrome/common/pref_names.h" | 31 #include "chrome/common/pref_names.h" |
| 32 #include "chrome/common/url_constants.h" | 32 #include "chrome/common/url_constants.h" |
| 33 #include "content/public/browser/navigation_entry.h" | 33 #include "content/public/browser/navigation_entry.h" |
| 34 #include "content/public/browser/notification_details.h" | 34 #include "content/public/browser/notification_details.h" |
| 35 #include "content/public/browser/notification_service.h" | 35 #include "content/public/browser/notification_service.h" |
| 36 #include "sync/protocol/session_specifics.pb.h" | 36 #include "sync/protocol/session_specifics.pb.h" |
| 37 #include "sync/syncable/syncable.h" | 37 #include "sync/syncable/syncable.h" |
| 38 #include "sync/util/get_session_name.h" | 38 #include "sync/util/get_session_name.h" |
| 39 #include "sync/util/time.h" |
| 39 #if defined(OS_LINUX) | 40 #if defined(OS_LINUX) |
| 40 #include "base/linux_util.h" | 41 #include "base/linux_util.h" |
| 41 #elif defined(OS_WIN) | 42 #elif defined(OS_WIN) |
| 42 #include <windows.h> | 43 #include <windows.h> |
| 43 #elif defined(OS_ANDROID) | 44 #elif defined(OS_ANDROID) |
| 44 #include "sync/util/session_utils_android.h" | 45 #include "sync/util/session_utils_android.h" |
| 45 #endif | 46 #endif |
| 46 | 47 |
| 47 using content::BrowserThread; | 48 using content::BrowserThread; |
| 48 using content::NavigationEntry; | 49 using content::NavigationEntry; |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 window_s.set_browser_type( | 218 window_s.set_browser_type( |
| 218 sync_pb::SessionWindow_BrowserType_TYPE_TABBED); | 219 sync_pb::SessionWindow_BrowserType_TYPE_TABBED); |
| 219 } else { | 220 } else { |
| 220 window_s.set_browser_type( | 221 window_s.set_browser_type( |
| 221 sync_pb::SessionWindow_BrowserType_TYPE_POPUP); | 222 sync_pb::SessionWindow_BrowserType_TYPE_POPUP); |
| 222 } | 223 } |
| 223 | 224 |
| 224 // Store the order of tabs. | 225 // Store the order of tabs. |
| 225 bool found_tabs = false; | 226 bool found_tabs = false; |
| 226 for (int j = 0; j < (*i)->GetTabCount(); ++j) { | 227 for (int j = 0; j < (*i)->GetTabCount(); ++j) { |
| 227 const SessionTab* tab; | |
| 228 SessionID::id_type tab_id = (*i)->GetTabIdAt(j); | 228 SessionID::id_type tab_id = (*i)->GetTabIdAt(j); |
| 229 | 229 |
| 230 if (reload_tabs) { | 230 if (reload_tabs) { |
| 231 SyncedTabDelegate* tab = (*i)->GetTabAt(j); | 231 SyncedTabDelegate* tab = (*i)->GetTabAt(j); |
| 232 // It's possible for GetTabAt to return a null tab if it's not in | 232 // It's possible for GetTabAt to return a null tab if it's not in |
| 233 // memory. We can assume this means the tab already existed but hasn't | 233 // memory. We can assume this means the tab already existed but hasn't |
| 234 // changed, so no need to reassociate. | 234 // changed, so no need to reassociate. |
| 235 if (tab && !AssociateTab(*tab, error)) { | 235 if (tab && !AssociateTab(*tab, error)) { |
| 236 // Association failed. Either we need to re-associate, or this is an | 236 // Association failed. Either we need to re-associate, or this is an |
| 237 // unrecoverable error. | 237 // unrecoverable error. |
| 238 return false; | 238 return false; |
| 239 } | 239 } |
| 240 } | 240 } |
| 241 | 241 |
| 242 // If the tab is valid, it would have been added to the tracker either | 242 // If the tab is valid, it would have been added to the tracker either |
| 243 // by the above AssociateTab call (at association time), or by the | 243 // by the above AssociateTab call (at association time), or by the |
| 244 // change processor calling AssociateTab for all modified tabs. | 244 // change processor calling AssociateTab for all modified tabs. |
| 245 // Therefore, we can key whether this window has valid tabs based on | 245 // Therefore, we can key whether this window has valid tabs based on |
| 246 // the tab's presence in the tracker. | 246 // the tab's presence in the tracker. |
| 247 const SyncedSessionTab* tab; |
| 247 if (synced_session_tracker_.LookupSessionTab(local_tag, tab_id, &tab)) { | 248 if (synced_session_tracker_.LookupSessionTab(local_tag, tab_id, &tab)) { |
| 248 found_tabs = true; | 249 found_tabs = true; |
| 249 window_s.add_tab(tab_id); | 250 window_s.add_tab(tab_id); |
| 250 } | 251 } |
| 251 } | 252 } |
| 252 // Only add a window if it contains valid tabs. | 253 // Only add a window if it contains valid tabs. |
| 253 if (found_tabs) { | 254 if (found_tabs) { |
| 254 sync_pb::SessionWindow* header_window = header_s->add_window(); | 255 sync_pb::SessionWindow* header_window = header_s->add_window(); |
| 255 *header_window = window_s; | 256 *header_window = window_s; |
| 256 | 257 |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 bool SessionModelAssociator::WriteTabContentsToSyncModel(TabLink* tab_link, | 362 bool SessionModelAssociator::WriteTabContentsToSyncModel(TabLink* tab_link, |
| 362 SyncError* error) { | 363 SyncError* error) { |
| 363 DCHECK(CalledOnValidThread()); | 364 DCHECK(CalledOnValidThread()); |
| 364 const SyncedTabDelegate& tab = *(tab_link->tab()); | 365 const SyncedTabDelegate& tab = *(tab_link->tab()); |
| 365 const SyncedWindowDelegate& window = | 366 const SyncedWindowDelegate& window = |
| 366 *SyncedWindowDelegate::FindSyncedWindowDelegateWithId( | 367 *SyncedWindowDelegate::FindSyncedWindowDelegateWithId( |
| 367 tab.GetWindowId()); | 368 tab.GetWindowId()); |
| 368 int64 sync_id = tab_link->sync_id(); | 369 int64 sync_id = tab_link->sync_id(); |
| 369 GURL old_tab_url = tab_link->url(); | 370 GURL old_tab_url = tab_link->url(); |
| 370 | 371 |
| 372 // Load the last stored version of this tab so we can compare changes. If this |
| 373 // is a new tab, session_tab will be a blank/newly created SessionTab object. |
| 374 SyncedSessionTab* session_tab = |
| 375 synced_session_tracker_.GetTab(GetCurrentMachineTag(), |
| 376 tab.GetSessionId()); |
| 377 |
| 371 // We build a clean session specifics directly from the tab data. | 378 // We build a clean session specifics directly from the tab data. |
| 372 sync_pb::SessionSpecifics session_s; | 379 sync_pb::SessionSpecifics session_s; |
| 373 session_s.set_session_tag(GetCurrentMachineTag()); | 380 session_s.set_session_tag(GetCurrentMachineTag()); |
| 374 sync_pb::SessionTab* tab_s = session_s.mutable_tab(); | 381 sync_pb::SessionTab* tab_s = session_s.mutable_tab(); |
| 375 SessionID::id_type tab_id = tab.GetSessionId(); | 382 |
| 376 tab_s->set_tab_id(tab_id); | 383 GURL new_url; |
| 377 tab_s->set_window_id(tab.GetWindowId()); | 384 AssociateTabContents(window, tab, session_tab, tab_s, &new_url); |
| 378 const int current_index = tab.GetCurrentEntryIndex(); | 385 |
| 379 const int min_index = std::max(0, | 386 // Trigger the favicon load if needed. We do this before opening the write |
| 380 current_index - kMaxSyncNavigationCount); | 387 // transaction to avoid jank. |
| 381 const int max_index = std::min(current_index + kMaxSyncNavigationCount, | 388 tab_link->set_url(new_url); |
| 382 tab.GetEntryCount()); | 389 if (new_url != old_tab_url) { |
| 383 const int pending_index = tab.GetPendingEntryIndex(); | 390 LoadFaviconForTab(tab_link); |
| 384 tab_s->set_pinned(window.IsTabPinned(&tab)); | |
| 385 if (tab.HasExtensionAppId()) { | |
| 386 tab_s->set_extension_app_id(tab.GetExtensionAppId()); | |
| 387 } | 391 } |
| 388 tab_s->mutable_navigation()->Clear(); | |
| 389 for (int i = min_index; i < max_index; ++i) { | |
| 390 const NavigationEntry* entry = (i == pending_index) ? | |
| 391 tab.GetPendingEntry() : tab.GetEntryAtIndex(i); | |
| 392 DCHECK(entry); | |
| 393 if (entry->GetVirtualURL().is_valid()) { | |
| 394 if (i == current_index && entry->GetVirtualURL().is_valid()) { | |
| 395 tab_link->set_url(entry->GetVirtualURL()); | |
| 396 DVLOG(1) << "Associating tab " << tab_id << " with sync id " << sync_id | |
| 397 << ", url " << entry->GetVirtualURL().spec() | |
| 398 << " and title " << entry->GetTitle(); | |
| 399 } | |
| 400 TabNavigation tab_nav; | |
| 401 tab_nav.SetFromNavigationEntry(*entry); | |
| 402 sync_pb::TabNavigation* nav_s = tab_s->add_navigation(); | |
| 403 PopulateSessionSpecificsNavigation(&tab_nav, nav_s); | |
| 404 } | |
| 405 } | |
| 406 tab_s->set_current_navigation_index(current_index); | |
| 407 | 392 |
| 408 // Convert to a local representation and store in synced session tracker for | 393 // Update our last modified time. |
| 409 // bookkeeping purposes. | |
| 410 SessionTab* session_tab = | |
| 411 synced_session_tracker_.GetTab(GetCurrentMachineTag(), | |
| 412 tab_s->tab_id()); | |
| 413 synced_session_tracker_.GetSession(GetCurrentMachineTag())->modified_time = | 394 synced_session_tracker_.GetSession(GetCurrentMachineTag())->modified_time = |
| 414 base::Time::Now(); | 395 base::Time::Now(); |
| 415 PopulateSessionTabFromSpecifics(*tab_s, | |
| 416 base::Time::Now(), | |
| 417 session_tab); | |
| 418 | |
| 419 // If the url changed, kick off the favicon load for the new url. | |
| 420 bool url_changed = false; | |
| 421 if (tab_link->url().is_valid() && tab_link->url() != old_tab_url) { | |
| 422 url_changed = true; | |
| 423 LoadFaviconForTab(tab_link); | |
| 424 } | |
| 425 | 396 |
| 426 sync_api::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare()); | 397 sync_api::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare()); |
| 427 sync_api::WriteNode tab_node(&trans); | 398 sync_api::WriteNode tab_node(&trans); |
| 428 if (!tab_node.InitByIdLookup(sync_id)) { | 399 if (!tab_node.InitByIdLookup(sync_id)) { |
| 429 if (error) { | 400 if (error) { |
| 430 *error = error_handler_->CreateAndUploadError( | 401 *error = error_handler_->CreateAndUploadError( |
| 431 FROM_HERE, | 402 FROM_HERE, |
| 432 "Failed to look up local tab node", | 403 "Failed to look up local tab node", |
| 433 model_type()); | 404 model_type()); |
| 434 } | 405 } |
| 435 return false; | 406 return false; |
| 436 } | 407 } |
| 437 | 408 |
| 438 // Preserve the existing favicon only if the url didn't change. | 409 if (new_url == old_tab_url) { |
| 439 if (!url_changed) { | 410 // Load the old specifics and copy over the favicon data if needed. |
| 440 tab_s->set_favicon(tab_node.GetSessionSpecifics().tab().favicon()); | 411 // TODO(zea): store local favicons in the |synced_favicons_| map and use |
| 441 tab_s->set_favicon_source( | 412 // that instead of reading from sync. This will be necessary to switch to |
| 442 tab_node.GetSessionSpecifics().tab().favicon_source()); | 413 // the new api. |
| 443 } // else store the empty favicon data back in. | 414 const sync_pb::SessionSpecifics old_specifics = |
| 415 tab_node.GetSessionSpecifics(); |
| 416 tab_s->set_favicon(old_specifics.tab().favicon()); |
| 417 tab_s->set_favicon_source(old_specifics.tab().favicon_source()); |
| 418 } |
| 444 | 419 |
| 445 // Write into the actual sync model. | 420 // Write into the actual sync model. |
| 446 tab_node.SetSessionSpecifics(session_s); | 421 tab_node.SetSessionSpecifics(session_s); |
| 447 | 422 |
| 448 return true; | 423 return true; |
| 449 } | 424 } |
| 450 | 425 |
| 426 // Builds |sync_tab| by combining data from |prev_tab| and |new_tab|. Updates |
| 427 // |prev_tab| to reflect the newest version. |
| 428 // Timestamps are chosen from either |prev_tab| or base::Time::Now() based on |
| 429 // the following rules: |
| 430 // 1. If a navigation exists in both |new_tab| and |prev_tab|, as determined |
| 431 // by the unique id, and the navigation didn't just become the current |
| 432 // navigation, we preserve the old timestamp. |
| 433 // 2. If the navigation exists in both but just become the current navigation |
| 434 // (e.g. the user went back in history to this navigation), we update the |
| 435 // timestamp to Now(). |
| 436 // 3. All new navigations not present in |prev_tab| have their timestamps set to |
| 437 // Now(). |
| 438 void SessionModelAssociator::AssociateTabContents( |
| 439 const SyncedWindowDelegate& window, |
| 440 const SyncedTabDelegate& new_tab, |
| 441 SyncedSessionTab* prev_tab, |
| 442 sync_pb::SessionTab* sync_tab, |
| 443 GURL* new_url) { |
| 444 DCHECK(prev_tab); |
| 445 DCHECK(sync_tab); |
| 446 DCHECK(new_url); |
| 447 SessionID::id_type tab_id = new_tab.GetSessionId(); |
| 448 sync_tab->set_tab_id(tab_id); |
| 449 sync_tab->set_window_id(new_tab.GetWindowId()); |
| 450 const int current_index = new_tab.GetCurrentEntryIndex(); |
| 451 sync_tab->set_current_navigation_index(current_index); |
| 452 const int min_index = std::max(0, |
| 453 current_index - kMaxSyncNavigationCount); |
| 454 const int max_index = std::min(current_index + kMaxSyncNavigationCount, |
| 455 new_tab.GetEntryCount()); |
| 456 const int pending_index = new_tab.GetPendingEntryIndex(); |
| 457 sync_tab->set_pinned(window.IsTabPinned(&new_tab)); |
| 458 if (new_tab.HasExtensionAppId()) { |
| 459 sync_tab->set_extension_app_id(new_tab.GetExtensionAppId()); |
| 460 } |
| 461 |
| 462 sync_tab->mutable_navigation()->Clear(); |
| 463 std::vector<SyncedTabNavigation>::const_iterator prev_nav_iter; |
| 464 for (int i = min_index; i < max_index; ++i) { |
| 465 const NavigationEntry* entry = (i == pending_index) ? |
| 466 new_tab.GetPendingEntry() : new_tab.GetEntryAtIndex(i); |
| 467 DCHECK(entry); |
| 468 if (i == min_index) { |
| 469 // Find the location of the first navigation within the previous list of |
| 470 // navigations. We only need to do this once, as all subsequent |
| 471 // navigations are either contiguous or completely new. |
| 472 for (prev_nav_iter = prev_tab->synced_tab_navigations.begin(); |
| 473 prev_nav_iter != prev_tab->synced_tab_navigations.end(); |
| 474 ++prev_nav_iter) { |
| 475 if (prev_nav_iter->unique_id() == entry->GetUniqueID()) |
| 476 break; |
| 477 } |
| 478 } |
| 479 if (entry->GetVirtualURL().is_valid()) { |
| 480 if (i == current_index) { |
| 481 *new_url = GURL(entry->GetVirtualURL().spec()); |
| 482 DVLOG(1) << "Associating local tab " << new_tab.GetSessionId() |
| 483 << " with url " << new_url->spec() << " and title " |
| 484 << entry->GetTitle(); |
| 485 |
| 486 } |
| 487 sync_pb::TabNavigation* sync_nav = sync_tab->add_navigation(); |
| 488 PopulateSessionSpecificsNavigation(*entry, sync_nav); |
| 489 |
| 490 // If this navigation is an old one, reuse the old timestamp. Otherwise we |
| 491 // leave the timestamp as the current time. |
| 492 if (prev_nav_iter != prev_tab->synced_tab_navigations.end() && |
| 493 prev_nav_iter->unique_id() == entry->GetUniqueID()) { |
| 494 // Check that we haven't gone back/foward in the nav stack to this page |
| 495 // (if so, we want to refresh the timestamp). |
| 496 if (!(current_index != prev_tab->current_navigation_index && |
| 497 current_index == i)) { |
| 498 sync_nav->set_timestamp(TimeToProtoTime(prev_nav_iter->timestamp())); |
| 499 DVLOG(2) << "Nav to " << sync_nav->virtual_url() << " already known, " |
| 500 << "reusing old timestamp " << sync_nav->timestamp(); |
| 501 } |
| 502 // Even if the user went back in their history, they may have skipped |
| 503 // over navigations, so the subsequent navigation entries may need their |
| 504 // old timestamps preserved. |
| 505 ++prev_nav_iter; |
| 506 } |
| 507 } |
| 508 } |
| 509 |
| 510 // Now update our local version with the newest data. |
| 511 PopulateSessionTabFromSpecifics(*sync_tab, |
| 512 base::Time::Now(), |
| 513 prev_tab); |
| 514 } |
| 515 |
| 451 void SessionModelAssociator::LoadFaviconForTab(TabLink* tab_link) { | 516 void SessionModelAssociator::LoadFaviconForTab(TabLink* tab_link) { |
| 452 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 517 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
| 453 if (!command_line.HasSwitch(switches::kSyncTabFavicons)) | 518 if (!command_line.HasSwitch(switches::kSyncTabFavicons)) |
| 454 return; | 519 return; |
| 455 FaviconService* favicon_service = | 520 FaviconService* favicon_service = |
| 456 profile_->GetFaviconService(Profile::EXPLICIT_ACCESS); | 521 profile_->GetFaviconService(Profile::EXPLICIT_ACCESS); |
| 457 if (!favicon_service) | 522 if (!favicon_service) |
| 458 return; | 523 return; |
| 459 SessionID::id_type tab_id = tab_link->tab()->GetSessionId(); | 524 SessionID::id_type tab_id = tab_link->tab()->GetSessionId(); |
| 460 if (tab_link->favicon_load_handle()) { | 525 if (tab_link->favicon_load_handle()) { |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 550 LoadFaviconForTab(tab_iter->second.get()); | 615 LoadFaviconForTab(tab_iter->second.get()); |
| 551 } | 616 } |
| 552 } | 617 } |
| 553 } | 618 } |
| 554 } | 619 } |
| 555 | 620 |
| 556 // Static | 621 // Static |
| 557 // TODO(zea): perhaps sync state (scroll position, form entries, etc.) as well? | 622 // TODO(zea): perhaps sync state (scroll position, form entries, etc.) as well? |
| 558 // See http://crbug.com/67068. | 623 // See http://crbug.com/67068. |
| 559 void SessionModelAssociator::PopulateSessionSpecificsNavigation( | 624 void SessionModelAssociator::PopulateSessionSpecificsNavigation( |
| 560 const TabNavigation* navigation, | 625 const NavigationEntry& navigation, |
| 561 sync_pb::TabNavigation* tab_navigation) { | 626 sync_pb::TabNavigation* tab_navigation) { |
| 562 tab_navigation->set_index(navigation->index()); | 627 tab_navigation->set_virtual_url(navigation.GetVirtualURL().spec()); |
| 563 tab_navigation->set_virtual_url(navigation->virtual_url().spec()); | |
| 564 // FIXME(zea): Support referrer policy? | 628 // FIXME(zea): Support referrer policy? |
| 565 tab_navigation->set_referrer(navigation->referrer().url.spec()); | 629 tab_navigation->set_referrer(navigation.GetReferrer().url.spec()); |
| 566 tab_navigation->set_title(UTF16ToUTF8(navigation->title())); | 630 tab_navigation->set_title(UTF16ToUTF8(navigation.GetTitle())); |
| 567 switch (navigation->transition()) { | 631 switch (navigation.GetTransitionType()) { |
| 568 case content::PAGE_TRANSITION_LINK: | 632 case content::PAGE_TRANSITION_LINK: |
| 569 tab_navigation->set_page_transition( | 633 tab_navigation->set_page_transition( |
| 570 sync_pb::TabNavigation_PageTransition_LINK); | 634 sync_pb::TabNavigation_PageTransition_LINK); |
| 571 break; | 635 break; |
| 572 case content::PAGE_TRANSITION_TYPED: | 636 case content::PAGE_TRANSITION_TYPED: |
| 573 tab_navigation->set_page_transition( | 637 tab_navigation->set_page_transition( |
| 574 sync_pb::TabNavigation_PageTransition_TYPED); | 638 sync_pb::TabNavigation_PageTransition_TYPED); |
| 575 break; | 639 break; |
| 576 case content::PAGE_TRANSITION_AUTO_BOOKMARK: | 640 case content::PAGE_TRANSITION_AUTO_BOOKMARK: |
| 577 tab_navigation->set_page_transition( | 641 tab_navigation->set_page_transition( |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 622 sync_pb::TabNavigation_PageTransitionQualifier_CLIENT_REDIRECT); | 686 sync_pb::TabNavigation_PageTransitionQualifier_CLIENT_REDIRECT); |
| 623 break; | 687 break; |
| 624 case content::PAGE_TRANSITION_SERVER_REDIRECT: | 688 case content::PAGE_TRANSITION_SERVER_REDIRECT: |
| 625 tab_navigation->set_navigation_qualifier( | 689 tab_navigation->set_navigation_qualifier( |
| 626 sync_pb::TabNavigation_PageTransitionQualifier_SERVER_REDIRECT); | 690 sync_pb::TabNavigation_PageTransitionQualifier_SERVER_REDIRECT); |
| 627 break; | 691 break; |
| 628 default: | 692 default: |
| 629 tab_navigation->set_page_transition( | 693 tab_navigation->set_page_transition( |
| 630 sync_pb::TabNavigation_PageTransition_TYPED); | 694 sync_pb::TabNavigation_PageTransition_TYPED); |
| 631 } | 695 } |
| 696 tab_navigation->set_unique_id(navigation.GetUniqueID()); |
| 697 tab_navigation->set_timestamp(TimeToProtoTime(base::Time::Now())); |
| 632 } | 698 } |
| 633 | 699 |
| 634 void SessionModelAssociator::Associate(const SyncedTabDelegate* tab, | 700 void SessionModelAssociator::Associate(const SyncedTabDelegate* tab, |
| 635 int64 sync_id) { | 701 int64 sync_id) { |
| 636 NOTIMPLEMENTED(); | 702 NOTIMPLEMENTED(); |
| 637 } | 703 } |
| 638 | 704 |
| 639 void SessionModelAssociator::Disassociate(int64 sync_id) { | 705 void SessionModelAssociator::Disassociate(int64 sync_id) { |
| 640 DCHECK(CalledOnValidThread()); | 706 DCHECK(CalledOnValidThread()); |
| 641 NOTIMPLEMENTED(); | 707 NOTIMPLEMENTED(); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 707 SyncError SessionModelAssociator::DisassociateModels() { | 773 SyncError SessionModelAssociator::DisassociateModels() { |
| 708 DCHECK(CalledOnValidThread()); | 774 DCHECK(CalledOnValidThread()); |
| 709 DVLOG(1) << "Disassociating local session " << GetCurrentMachineTag(); | 775 DVLOG(1) << "Disassociating local session " << GetCurrentMachineTag(); |
| 710 synced_session_tracker_.Clear(); | 776 synced_session_tracker_.Clear(); |
| 711 tab_map_.clear(); | 777 tab_map_.clear(); |
| 712 tab_pool_.clear(); | 778 tab_pool_.clear(); |
| 713 local_session_syncid_ = sync_api::kInvalidId; | 779 local_session_syncid_ = sync_api::kInvalidId; |
| 714 current_machine_tag_ = ""; | 780 current_machine_tag_ = ""; |
| 715 current_session_name_ = ""; | 781 current_session_name_ = ""; |
| 716 load_consumer_.CancelAllRequests(); | 782 load_consumer_.CancelAllRequests(); |
| 783 synced_favicons_.clear(); |
| 784 synced_favicon_pages_.clear(); |
| 785 synced_favicon_usage_.clear(); |
| 717 | 786 |
| 718 // There is no local model stored with which to disassociate, just notify | 787 // There is no local model stored with which to disassociate, just notify |
| 719 // foreign session handlers. | 788 // foreign session handlers. |
| 720 content::NotificationService::current()->Notify( | 789 content::NotificationService::current()->Notify( |
| 721 chrome::NOTIFICATION_FOREIGN_SESSION_DISABLED, | 790 chrome::NOTIFICATION_FOREIGN_SESSION_DISABLED, |
| 722 content::Source<Profile>(sync_service_->profile()), | 791 content::Source<Profile>(sync_service_->profile()), |
| 723 content::NotificationService::NoDetails()); | 792 content::NotificationService::NoDetails()); |
| 724 return SyncError(); | 793 return SyncError(); |
| 725 } | 794 } |
| 726 | 795 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 748 } | 817 } |
| 749 | 818 |
| 750 void SessionModelAssociator::OnSessionNameInitialized( | 819 void SessionModelAssociator::OnSessionNameInitialized( |
| 751 const std::string& name) { | 820 const std::string& name) { |
| 752 DCHECK(CalledOnValidThread()); | 821 DCHECK(CalledOnValidThread()); |
| 753 // Only use the default machine name if it hasn't already been set. | 822 // Only use the default machine name if it hasn't already been set. |
| 754 if (current_session_name_.empty()) | 823 if (current_session_name_.empty()) |
| 755 current_session_name_ = name; | 824 current_session_name_ = name; |
| 756 } | 825 } |
| 757 | 826 |
| 827 bool SessionModelAssociator::GetSyncedFaviconForPageURL( |
| 828 const std::string& url, |
| 829 std::string* png_favicon) const { |
| 830 std::map<std::string, std::string>::const_iterator iter = |
| 831 synced_favicon_pages_.find(url); |
| 832 if (iter == synced_favicon_pages_.end()) |
| 833 return false; |
| 834 const std::string& favicon = *(synced_favicons_.find(iter->second)->second); |
| 835 png_favicon->assign(favicon); |
| 836 DCHECK_GT(favicon.size(), 0U); |
| 837 return true; |
| 838 } |
| 839 |
| 758 void SessionModelAssociator::InitializeCurrentSessionName() { | 840 void SessionModelAssociator::InitializeCurrentSessionName() { |
| 759 DCHECK(CalledOnValidThread()); | 841 DCHECK(CalledOnValidThread()); |
| 760 if (setup_for_test_) { | 842 if (setup_for_test_) { |
| 761 OnSessionNameInitialized("TestSessionName"); | 843 OnSessionNameInitialized("TestSessionName"); |
| 762 } else { | 844 } else { |
| 763 browser_sync::GetSessionName( | 845 browser_sync::GetSessionName( |
| 764 BrowserThread::GetBlockingPool(), | 846 BrowserThread::GetBlockingPool(), |
| 765 base::Bind(&SessionModelAssociator::OnSessionNameInitialized, | 847 base::Bind(&SessionModelAssociator::OnSessionNameInitialized, |
| 766 AsWeakPtr())); | 848 AsWeakPtr())); |
| 767 } | 849 } |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 866 modification_time, | 948 modification_time, |
| 867 foreign_session->windows[window_id], | 949 foreign_session->windows[window_id], |
| 868 &synced_session_tracker_); | 950 &synced_session_tracker_); |
| 869 } | 951 } |
| 870 | 952 |
| 871 // Delete any closed windows and unused tabs as necessary. | 953 // Delete any closed windows and unused tabs as necessary. |
| 872 synced_session_tracker_.CleanupSession(foreign_session_tag); | 954 synced_session_tracker_.CleanupSession(foreign_session_tag); |
| 873 } else if (specifics.has_tab()) { | 955 } else if (specifics.has_tab()) { |
| 874 const sync_pb::SessionTab& tab_s = specifics.tab(); | 956 const sync_pb::SessionTab& tab_s = specifics.tab(); |
| 875 SessionID::id_type tab_id = tab_s.tab_id(); | 957 SessionID::id_type tab_id = tab_s.tab_id(); |
| 876 SessionTab* tab = | 958 SyncedSessionTab* tab = |
| 877 synced_session_tracker_.GetTab(foreign_session_tag, tab_id); | 959 synced_session_tracker_.GetTab(foreign_session_tag, tab_id); |
| 960 |
| 961 // Figure out what the previous url for this tab was (may be empty string |
| 962 // if this is a new tab). |
| 963 std::string previous_url; |
| 964 if (tab->navigations.size() > 0) { |
| 965 int selected_index = tab->current_navigation_index; |
| 966 selected_index = std::max( |
| 967 0, |
| 968 std::min(selected_index, |
| 969 static_cast<int>(tab->navigations.size() - 1))); |
| 970 if (tab->navigations[selected_index].virtual_url().is_valid()) |
| 971 previous_url = tab->navigations[selected_index].virtual_url().spec(); |
| 972 } |
| 973 |
| 974 // Update SessionTab based on protobuf. |
| 878 PopulateSessionTabFromSpecifics(tab_s, modification_time, tab); | 975 PopulateSessionTabFromSpecifics(tab_s, modification_time, tab); |
| 976 |
| 977 // Also increments synced_favicon_usage_ and updates synced_favicon_pages_. |
| 879 LoadForeignTabFavicon(tab_s); | 978 LoadForeignTabFavicon(tab_s); |
| 979 |
| 980 // Now check to see if the favicon associated with the previous url is no |
| 981 // longer in use. This will have no effect if the current url matches the |
| 982 // previous url (LoadForeignTabFavicon increments, this decrements, no net |
| 983 // change in usage), or if the previous_url was not set (new tab). |
| 984 DecrementAndCleanFaviconForURL(previous_url); |
| 985 |
| 986 // Update the last modified time. |
| 880 if (foreign_session->modified_time < modification_time) | 987 if (foreign_session->modified_time < modification_time) |
| 881 foreign_session->modified_time = modification_time; | 988 foreign_session->modified_time = modification_time; |
| 882 } else { | 989 } else { |
| 883 LOG(WARNING) << "Ignoring foreign session node with missing header/tab " | 990 LOG(WARNING) << "Ignoring foreign session node with missing header/tab " |
| 884 << "fields and tag " << foreign_session_tag << "."; | 991 << "fields and tag " << foreign_session_tag << "."; |
| 885 } | 992 } |
| 886 } | 993 } |
| 887 | 994 |
| 995 void SessionModelAssociator::DecrementAndCleanFaviconForURL( |
| 996 std::string page_url) { |
| 997 if (page_url.empty()) |
| 998 return; |
| 999 std::map<std::string, std::string>::const_iterator iter = |
| 1000 synced_favicon_pages_.find(page_url); |
| 1001 if (iter != synced_favicon_pages_.end()) { |
| 1002 const std::string& favicon_url = iter->second; |
| 1003 synced_favicon_usage_[favicon_url]--; |
| 1004 if (synced_favicon_usage_[favicon_url] <= 0) { |
| 1005 // No more tabs using this favicon. Erase it. |
| 1006 synced_favicons_.erase(favicon_url); |
| 1007 // Erase the page mappings to the favicon url. We iterate through all |
| 1008 // page urls in case multiple pages share the same favicon. |
| 1009 std::map<std::string, std::string>::iterator page_iter; |
| 1010 for (page_iter = synced_favicon_pages_.begin(); |
| 1011 page_iter != synced_favicon_pages_.end();) { |
| 1012 std::map<std::string, std::string>::iterator to_delete = page_iter; |
| 1013 ++page_iter; |
| 1014 if (to_delete->second == favicon_url) { |
| 1015 synced_favicon_pages_.erase(to_delete); |
| 1016 } |
| 1017 } |
| 1018 // Lastly, erase the counts related to the favicon url. |
| 1019 synced_favicon_usage_.erase(favicon_url); |
| 1020 } |
| 1021 } |
| 1022 } |
| 1023 |
| 1024 size_t SessionModelAssociator::NumFaviconsForTesting() const { |
| 1025 return synced_favicons_.size(); |
| 1026 } |
| 1027 |
| 888 bool SessionModelAssociator::DisassociateForeignSession( | 1028 bool SessionModelAssociator::DisassociateForeignSession( |
| 889 const std::string& foreign_session_tag) { | 1029 const std::string& foreign_session_tag) { |
| 890 DCHECK(CalledOnValidThread()); | 1030 DCHECK(CalledOnValidThread()); |
| 891 if (foreign_session_tag == GetCurrentMachineTag()) { | 1031 if (foreign_session_tag == GetCurrentMachineTag()) { |
| 892 DVLOG(1) << "Local session deleted! Doing nothing until a navigation is " | 1032 DVLOG(1) << "Local session deleted! Doing nothing until a navigation is " |
| 893 << "triggered."; | 1033 << "triggered."; |
| 894 return false; | 1034 return false; |
| 895 } | 1035 } |
| 896 DVLOG(1) << "Disassociating session " << foreign_session_tag; | 1036 DVLOG(1) << "Disassociating session " << foreign_session_tag; |
| 897 return synced_session_tracker_.DeleteSession(foreign_session_tag); | 1037 return synced_session_tracker_.DeleteSession(foreign_session_tag); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 962 session_window->window_id.id(), | 1102 session_window->window_id.id(), |
| 963 tab_id, | 1103 tab_id, |
| 964 i); | 1104 i); |
| 965 } | 1105 } |
| 966 } | 1106 } |
| 967 | 1107 |
| 968 // Static | 1108 // Static |
| 969 void SessionModelAssociator::PopulateSessionTabFromSpecifics( | 1109 void SessionModelAssociator::PopulateSessionTabFromSpecifics( |
| 970 const sync_pb::SessionTab& specifics, | 1110 const sync_pb::SessionTab& specifics, |
| 971 const base::Time& mtime, | 1111 const base::Time& mtime, |
| 972 SessionTab* tab) { | 1112 SyncedSessionTab* tab) { |
| 973 DCHECK_EQ(tab->tab_id.id(), specifics.tab_id()); | 1113 DCHECK_EQ(tab->tab_id.id(), specifics.tab_id()); |
| 974 if (specifics.has_tab_id()) | 1114 if (specifics.has_tab_id()) |
| 975 tab->tab_id.set_id(specifics.tab_id()); | 1115 tab->tab_id.set_id(specifics.tab_id()); |
| 976 if (specifics.has_window_id()) | 1116 if (specifics.has_window_id()) |
| 977 tab->window_id.set_id(specifics.window_id()); | 1117 tab->window_id.set_id(specifics.window_id()); |
| 978 if (specifics.has_tab_visual_index()) | 1118 if (specifics.has_tab_visual_index()) |
| 979 tab->tab_visual_index = specifics.tab_visual_index(); | 1119 tab->tab_visual_index = specifics.tab_visual_index(); |
| 980 if (specifics.has_current_navigation_index()) | 1120 if (specifics.has_current_navigation_index()) |
| 981 tab->current_navigation_index = specifics.current_navigation_index(); | 1121 tab->current_navigation_index = specifics.current_navigation_index(); |
| 982 if (specifics.has_pinned()) | 1122 if (specifics.has_pinned()) |
| 983 tab->pinned = specifics.pinned(); | 1123 tab->pinned = specifics.pinned(); |
| 984 if (specifics.has_extension_app_id()) | 1124 if (specifics.has_extension_app_id()) |
| 985 tab->extension_app_id = specifics.extension_app_id(); | 1125 tab->extension_app_id = specifics.extension_app_id(); |
| 986 tab->timestamp = mtime; | 1126 tab->timestamp = mtime; |
| 987 tab->navigations.clear(); // In case we are reusing a previous SessionTab. | 1127 // Cleared in case we reuse a pre-existing SyncedSessionTab object. |
| 988 for (int i = 0; i < specifics.navigation_size(); i++) { | 1128 tab->navigations.clear(); |
| 989 AppendSessionTabNavigation(specifics.navigation(i), &tab->navigations); | 1129 tab->synced_tab_navigations.clear(); |
| 1130 for (int i = 0; i < specifics.navigation_size(); ++i) { |
| 1131 AppendSessionTabNavigation(specifics.navigation(i), |
| 1132 tab); |
| 990 } | 1133 } |
| 991 } | 1134 } |
| 992 | 1135 |
| 993 // Static | 1136 // Static |
| 994 void SessionModelAssociator::AppendSessionTabNavigation( | 1137 void SessionModelAssociator::AppendSessionTabNavigation( |
| 995 const sync_pb::TabNavigation& specifics, | 1138 const sync_pb::TabNavigation& specifics, |
| 996 std::vector<TabNavigation>* navigations) { | 1139 SyncedSessionTab* tab) { |
| 997 int index = 0; | 1140 int index = 0; |
| 998 GURL virtual_url; | 1141 GURL virtual_url; |
| 999 GURL referrer; | 1142 GURL referrer; |
| 1000 string16 title; | 1143 string16 title; |
| 1001 std::string state; | 1144 std::string state; |
| 1002 content::PageTransition transition(content::PAGE_TRANSITION_LINK); | 1145 content::PageTransition transition(content::PAGE_TRANSITION_LINK); |
| 1003 if (specifics.has_index()) | 1146 base::Time timestamp; |
| 1004 index = specifics.index(); | 1147 int unique_id = 0; |
| 1005 if (specifics.has_virtual_url()) { | 1148 if (specifics.has_virtual_url()) { |
| 1006 GURL gurl(specifics.virtual_url()); | 1149 GURL gurl(specifics.virtual_url()); |
| 1007 virtual_url = gurl; | 1150 virtual_url = gurl; |
| 1008 } | 1151 } |
| 1009 if (specifics.has_referrer()) { | 1152 if (specifics.has_referrer()) { |
| 1010 GURL gurl(specifics.referrer()); | 1153 GURL gurl(specifics.referrer()); |
| 1011 referrer = gurl; | 1154 referrer = gurl; |
| 1012 } | 1155 } |
| 1013 if (specifics.has_title()) | 1156 if (specifics.has_title()) |
| 1014 title = UTF8ToUTF16(specifics.title()); | 1157 title = UTF8ToUTF16(specifics.title()); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1064 break; | 1207 break; |
| 1065 case sync_pb:: | 1208 case sync_pb:: |
| 1066 TabNavigation_PageTransitionQualifier_SERVER_REDIRECT: | 1209 TabNavigation_PageTransitionQualifier_SERVER_REDIRECT: |
| 1067 transition = content::PAGE_TRANSITION_SERVER_REDIRECT; | 1210 transition = content::PAGE_TRANSITION_SERVER_REDIRECT; |
| 1068 break; | 1211 break; |
| 1069 default: | 1212 default: |
| 1070 transition = content::PAGE_TRANSITION_TYPED; | 1213 transition = content::PAGE_TRANSITION_TYPED; |
| 1071 } | 1214 } |
| 1072 } | 1215 } |
| 1073 } | 1216 } |
| 1074 TabNavigation tab_navigation( | 1217 if (specifics.has_timestamp()) { |
| 1218 timestamp = ProtoTimeToTime(specifics.timestamp()); |
| 1219 } |
| 1220 if (specifics.has_unique_id()) { |
| 1221 unique_id = specifics.unique_id(); |
| 1222 } |
| 1223 SyncedTabNavigation tab_navigation( |
| 1075 index, virtual_url, | 1224 index, virtual_url, |
| 1076 content::Referrer(referrer, WebKit::WebReferrerPolicyDefault), title, | 1225 content::Referrer(referrer, WebKit::WebReferrerPolicyDefault), title, |
| 1077 state, transition); | 1226 state, transition, unique_id, timestamp); |
| 1078 navigations->insert(navigations->end(), tab_navigation); | 1227 // We insert it twice, once for our SyncedTabNavigations, once for the normal |
| 1228 // TabNavigation (used by the session restore UI). |
| 1229 tab->synced_tab_navigations.insert(tab->synced_tab_navigations.end(), |
| 1230 tab_navigation); |
| 1231 tab->navigations.insert(tab->navigations.end(), |
| 1232 tab_navigation); |
| 1079 } | 1233 } |
| 1080 | 1234 |
| 1081 void SessionModelAssociator::LoadForeignTabFavicon( | 1235 void SessionModelAssociator::LoadForeignTabFavicon( |
| 1082 const sync_pb::SessionTab& tab) { | 1236 const sync_pb::SessionTab& tab) { |
| 1083 if (!tab.has_favicon() || tab.favicon().empty()) | 1237 if (!tab.has_favicon() || tab.favicon().empty()) |
| 1084 return; | 1238 return; |
| 1085 if (tab.favicon_type() != sync_pb::SessionTab::TYPE_WEB_FAVICON) { | 1239 if (!tab.has_favicon_type() || |
| 1240 tab.favicon_type() != sync_pb::SessionTab::TYPE_WEB_FAVICON) { |
| 1086 DVLOG(1) << "Ignoring non-web favicon."; | 1241 DVLOG(1) << "Ignoring non-web favicon."; |
| 1087 return; | 1242 return; |
| 1088 } | 1243 } |
| 1089 int current_navigation_index = tab.current_navigation_index(); | 1244 if (tab.navigation_size() == 0) |
| 1090 if (current_navigation_index < 0 || | |
| 1091 current_navigation_index >= tab.navigation_size()) { | |
| 1092 return; | 1245 return; |
| 1093 } | 1246 int selected_index = tab.current_navigation_index(); |
| 1094 GURL navigation_url(tab.navigation(current_navigation_index).virtual_url()); | 1247 selected_index = std::max( |
| 1248 0, |
| 1249 std::min(selected_index, |
| 1250 static_cast<int>(tab.navigation_size() - 1))); |
| 1251 GURL navigation_url(tab.navigation(selected_index).virtual_url()); |
| 1095 if (!navigation_url.is_valid()) | 1252 if (!navigation_url.is_valid()) |
| 1096 return; | 1253 return; |
| 1097 GURL favicon_source(tab.favicon_source()); | 1254 GURL favicon_source(tab.favicon_source()); |
| 1098 if (!favicon_source.is_valid()) | 1255 if (!favicon_source.is_valid()) |
| 1099 return; | 1256 return; |
| 1100 | 1257 |
| 1101 HistoryService* history = | |
| 1102 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); | |
| 1103 FaviconService* favicon_service = | |
| 1104 profile_->GetFaviconService(Profile::EXPLICIT_ACCESS); | |
| 1105 if (!history || !favicon_service) | |
| 1106 return; | |
| 1107 std::vector<unsigned char> icon_bytes; | |
| 1108 const std::string& favicon = tab.favicon(); | 1258 const std::string& favicon = tab.favicon(); |
| 1109 icon_bytes.assign(reinterpret_cast<const unsigned char*>(favicon.data()), | |
| 1110 reinterpret_cast<const unsigned char*>(favicon.data() + | |
| 1111 favicon.length())); | |
| 1112 DVLOG(1) << "Storing synced favicon for url " << navigation_url.spec() | 1259 DVLOG(1) << "Storing synced favicon for url " << navigation_url.spec() |
| 1113 << " with size " << icon_bytes.size() << " bytes."; | 1260 << " with size " << favicon.size() << " bytes."; |
| 1114 favicon_service->SetFavicon(navigation_url, | 1261 synced_favicons_[favicon_source.spec()] = |
| 1115 favicon_source, | 1262 make_linked_ptr<std::string>(new std::string(favicon)); |
| 1116 icon_bytes, | 1263 synced_favicon_usage_[favicon_source.spec()]++; |
| 1117 history::FAVICON); | 1264 synced_favicon_pages_[navigation_url.spec()] = favicon_source.spec(); |
| 1118 } | 1265 } |
| 1119 | 1266 |
| 1120 bool SessionModelAssociator::UpdateSyncModelDataFromClient(SyncError* error) { | 1267 bool SessionModelAssociator::UpdateSyncModelDataFromClient(SyncError* error) { |
| 1121 DCHECK(CalledOnValidThread()); | 1268 DCHECK(CalledOnValidThread()); |
| 1122 | 1269 |
| 1123 // Associate all open windows and their tabs. | 1270 // Associate all open windows and their tabs. |
| 1124 return AssociateWindows(true, error); | 1271 return AssociateWindows(true, error); |
| 1125 } | 1272 } |
| 1126 | 1273 |
| 1127 SessionModelAssociator::TabNodePool::TabNodePool( | 1274 SessionModelAssociator::TabNodePool::TabNodePool( |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1211 std::vector<const SessionWindow*>* windows) { | 1358 std::vector<const SessionWindow*>* windows) { |
| 1212 DCHECK(CalledOnValidThread()); | 1359 DCHECK(CalledOnValidThread()); |
| 1213 return synced_session_tracker_.LookupSessionWindows(tag, windows); | 1360 return synced_session_tracker_.LookupSessionWindows(tag, windows); |
| 1214 } | 1361 } |
| 1215 | 1362 |
| 1216 bool SessionModelAssociator::GetForeignTab( | 1363 bool SessionModelAssociator::GetForeignTab( |
| 1217 const std::string& tag, | 1364 const std::string& tag, |
| 1218 const SessionID::id_type tab_id, | 1365 const SessionID::id_type tab_id, |
| 1219 const SessionTab** tab) { | 1366 const SessionTab** tab) { |
| 1220 DCHECK(CalledOnValidThread()); | 1367 DCHECK(CalledOnValidThread()); |
| 1221 return synced_session_tracker_.LookupSessionTab(tag, tab_id, tab); | 1368 const SyncedSessionTab* synced_tab; |
| 1369 bool success = synced_session_tracker_.LookupSessionTab(tag, |
| 1370 tab_id, |
| 1371 &synced_tab); |
| 1372 if (success) |
| 1373 *tab = synced_tab; |
| 1374 return success; |
| 1222 } | 1375 } |
| 1223 | 1376 |
| 1224 void SessionModelAssociator::DeleteStaleSessions() { | 1377 void SessionModelAssociator::DeleteStaleSessions() { |
| 1225 DCHECK(CalledOnValidThread()); | 1378 DCHECK(CalledOnValidThread()); |
| 1226 std::vector<const SyncedSession*> sessions; | 1379 std::vector<const SyncedSession*> sessions; |
| 1227 if (!GetAllForeignSessions(&sessions)) | 1380 if (!GetAllForeignSessions(&sessions)) |
| 1228 return; // No foreign sessions. | 1381 return; // No foreign sessions. |
| 1229 | 1382 |
| 1230 // Iterate through all the sessions and delete any with age older than | 1383 // Iterate through all the sessions and delete any with age older than |
| 1231 // |stale_session_threshold_days_|. | 1384 // |stale_session_threshold_days_|. |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1360 bool SessionModelAssociator::CryptoReadyIfNecessary() { | 1513 bool SessionModelAssociator::CryptoReadyIfNecessary() { |
| 1361 // We only access the cryptographer while holding a transaction. | 1514 // We only access the cryptographer while holding a transaction. |
| 1362 sync_api::ReadTransaction trans(FROM_HERE, sync_service_->GetUserShare()); | 1515 sync_api::ReadTransaction trans(FROM_HERE, sync_service_->GetUserShare()); |
| 1363 const syncable::ModelTypeSet encrypted_types = | 1516 const syncable::ModelTypeSet encrypted_types = |
| 1364 sync_api::GetEncryptedTypes(&trans); | 1517 sync_api::GetEncryptedTypes(&trans); |
| 1365 return !encrypted_types.Has(SESSIONS) || | 1518 return !encrypted_types.Has(SESSIONS) || |
| 1366 sync_service_->IsCryptographerReady(&trans); | 1519 sync_service_->IsCryptographerReady(&trans); |
| 1367 } | 1520 } |
| 1368 | 1521 |
| 1369 } // namespace browser_sync | 1522 } // namespace browser_sync |
| OLD | NEW |