| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 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/win/jumplist.h" | 5 #include "chrome/browser/win/jumplist.h" |
| 6 | 6 |
| 7 #include "base/base_paths.h" | 7 #include "base/base_paths.h" |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/bind_helpers.h" | 9 #include "base/bind_helpers.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 #include "ui/gfx/image/image_family.h" | 49 #include "ui/gfx/image/image_family.h" |
| 50 #include "ui/gfx/image/image_skia.h" | 50 #include "ui/gfx/image/image_skia.h" |
| 51 #include "ui/gfx/image/image_skia_rep.h" | 51 #include "ui/gfx/image/image_skia_rep.h" |
| 52 #include "url/gurl.h" | 52 #include "url/gurl.h" |
| 53 | 53 |
| 54 using content::BrowserThread; | 54 using content::BrowserThread; |
| 55 using JumpListData = JumpList::JumpListData; | 55 using JumpListData = JumpList::JumpListData; |
| 56 | 56 |
| 57 namespace { | 57 namespace { |
| 58 | 58 |
| 59 // The default maximum number of items to display in JumpList is 10. |
| 60 // https://msdn.microsoft.com/library/windows/desktop/dd378398.aspx |
| 61 // The "Most visited" and "Recently closed" category titles always take 2 slots. |
| 62 // For the remaining 8 slots, we allocate 5 slots to "most-visited" items and 3 |
| 63 // slots to"recently-closed" items, respectively. |
| 64 constexpr size_t kMostVisitedItems = 5; |
| 65 constexpr size_t kRecentlyClosedItems = 3; |
| 66 |
| 59 // The number of updates to skip to alleviate the machine when a previous update | 67 // The number of updates to skip to alleviate the machine when a previous update |
| 60 // was too slow. | 68 // was too slow. |
| 61 constexpr int kUpdatesToSkipUnderHeavyLoad = 10; | 69 constexpr int kUpdatesToSkipUnderHeavyLoad = 10; |
| 62 | 70 |
| 63 // The delay before updating the JumpList to prevent update storms. | 71 // The delay before updating the JumpList to prevent update storms. |
| 64 constexpr base::TimeDelta kDelayForJumplistUpdate = | 72 constexpr base::TimeDelta kDelayForJumplistUpdate = |
| 65 base::TimeDelta::FromMilliseconds(3500); | 73 base::TimeDelta::FromMilliseconds(3500); |
| 66 | 74 |
| 67 // The maximum allowed time for JumpListUpdater::BeginUpdate. Updates taking | 75 // The maximum allowed time for JumpListUpdater::BeginUpdate. Updates taking |
| 68 // longer than this are discarded to prevent bogging down slow machines. | 76 // longer than this are discarded to prevent bogging down slow machines. |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 TabRestoreServiceFactory::GetForProfile(profile_); | 223 TabRestoreServiceFactory::GetForProfile(profile_); |
| 216 if (!tab_restore_service) | 224 if (!tab_restore_service) |
| 217 return; | 225 return; |
| 218 | 226 |
| 219 app_id_ = | 227 app_id_ = |
| 220 shell_integration::win::GetChromiumModelIdForProfile(profile_->GetPath()); | 228 shell_integration::win::GetChromiumModelIdForProfile(profile_->GetPath()); |
| 221 | 229 |
| 222 scoped_refptr<history::TopSites> top_sites = | 230 scoped_refptr<history::TopSites> top_sites = |
| 223 TopSitesFactory::GetForProfile(profile_); | 231 TopSitesFactory::GetForProfile(profile_); |
| 224 if (top_sites) { | 232 if (top_sites) { |
| 225 // TopSites updates itself after a delay. This is especially noticable when | |
| 226 // your profile is empty. Ask TopSites to update itself when jumplist is | |
| 227 // initialized. | |
| 228 top_sites->SyncWithHistory(); | |
| 229 // Register as TopSitesObserver so that we can update ourselves when the | 233 // Register as TopSitesObserver so that we can update ourselves when the |
| 230 // TopSites changes. | 234 // TopSites changes. TopSites updates itself after a delay. This is |
| 235 // especially noticable when your profile is empty. |
| 231 top_sites->AddObserver(this); | 236 top_sites->AddObserver(this); |
| 232 } | 237 } |
| 233 tab_restore_service->AddObserver(this); | 238 tab_restore_service->AddObserver(this); |
| 234 pref_change_registrar_.reset(new PrefChangeRegistrar); | 239 pref_change_registrar_.reset(new PrefChangeRegistrar); |
| 235 pref_change_registrar_->Init(profile_->GetPrefs()); | 240 pref_change_registrar_->Init(profile_->GetPrefs()); |
| 236 pref_change_registrar_->Add( | 241 pref_change_registrar_->Add( |
| 237 prefs::kIncognitoModeAvailability, | 242 prefs::kIncognitoModeAvailability, |
| 238 base::Bind(&JumpList::OnIncognitoAvailabilityChanged, this)); | 243 base::Bind(&JumpList::OnIncognitoAvailabilityChanged, this)); |
| 239 } | 244 } |
| 240 | 245 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 | 282 |
| 278 void JumpList::ShutdownOnUIThread() { | 283 void JumpList::ShutdownOnUIThread() { |
| 279 DCHECK(CalledOnValidThread()); | 284 DCHECK(CalledOnValidThread()); |
| 280 Terminate(); | 285 Terminate(); |
| 281 } | 286 } |
| 282 | 287 |
| 283 void JumpList::OnMostVisitedURLsAvailable( | 288 void JumpList::OnMostVisitedURLsAvailable( |
| 284 const history::MostVisitedURLList& urls) { | 289 const history::MostVisitedURLList& urls) { |
| 285 DCHECK(CalledOnValidThread()); | 290 DCHECK(CalledOnValidThread()); |
| 286 | 291 |
| 287 // At most 9 JumpList items can be displayed for the "Most Visited" | |
| 288 // category. | |
| 289 const int kMostVistedCount = 9; | |
| 290 { | 292 { |
| 291 JumpListData* data = &jumplist_data_->data; | 293 JumpListData* data = &jumplist_data_->data; |
| 292 base::AutoLock auto_lock(data->list_lock_); | 294 base::AutoLock auto_lock(data->list_lock_); |
| 293 data->most_visited_pages_.clear(); | 295 data->most_visited_pages_.clear(); |
| 294 | 296 |
| 295 for (size_t i = 0; i < urls.size() && i < kMostVistedCount; i++) { | 297 for (size_t i = 0; i < urls.size() && i < kMostVisitedItems; i++) { |
| 296 const history::MostVisitedURL& url = urls[i]; | 298 const history::MostVisitedURL& url = urls[i]; |
| 297 scoped_refptr<ShellLinkItem> link = CreateShellLink(); | 299 scoped_refptr<ShellLinkItem> link = CreateShellLink(); |
| 298 std::string url_string = url.url.spec(); | 300 std::string url_string = url.url.spec(); |
| 299 base::string16 url_string_wide = base::UTF8ToUTF16(url_string); | 301 base::string16 url_string_wide = base::UTF8ToUTF16(url_string); |
| 300 link->GetCommandLine()->AppendArgNative(url_string_wide); | 302 link->GetCommandLine()->AppendArgNative(url_string_wide); |
| 301 link->GetCommandLine()->AppendSwitchASCII( | 303 link->GetCommandLine()->AppendSwitchASCII( |
| 302 switches::kWinJumplistAction, jumplist::kMostVisitedCategory); | 304 switches::kWinJumplistAction, jumplist::kMostVisitedCategory); |
| 303 link->set_title(!url.title.empty() ? url.title : url_string_wide); | 305 link->set_title(!url.title.empty() ? url.title : url_string_wide); |
| 304 link->set_url(url_string); | 306 link->set_url(url_string); |
| 305 data->most_visited_pages_.push_back(link); | 307 data->most_visited_pages_.push_back(link); |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 if (timer_most_visited_.IsRunning()) { | 525 if (timer_most_visited_.IsRunning()) { |
| 524 timer_most_visited_.Reset(); | 526 timer_most_visited_.Reset(); |
| 525 } else { | 527 } else { |
| 526 timer_most_visited_.Start( | 528 timer_most_visited_.Start( |
| 527 FROM_HERE, kDelayForJumplistUpdate, | 529 FROM_HERE, kDelayForJumplistUpdate, |
| 528 base::Bind(&JumpList::DeferredTopSitesChanged, base::Unretained(this))); | 530 base::Bind(&JumpList::DeferredTopSitesChanged, base::Unretained(this))); |
| 529 } | 531 } |
| 530 } | 532 } |
| 531 | 533 |
| 532 void JumpList::DeferredTopSitesChanged() { | 534 void JumpList::DeferredTopSitesChanged() { |
| 535 DCHECK(CalledOnValidThread()); |
| 536 |
| 533 if (updates_to_skip_ > 0) { | 537 if (updates_to_skip_ > 0) { |
| 534 --updates_to_skip_; | 538 --updates_to_skip_; |
| 535 return; | 539 return; |
| 536 } | 540 } |
| 537 | 541 |
| 542 // Opening the first tab in one session triggers a TopSite history sync. |
| 543 // Delay this sync till the first tab is closed to allow the "recently closed" |
| 544 // category from last session to stay longer. |
| 545 if (!has_tab_closed_) |
| 546 return; |
| 547 |
| 538 scoped_refptr<history::TopSites> top_sites = | 548 scoped_refptr<history::TopSites> top_sites = |
| 539 TopSitesFactory::GetForProfile(profile_); | 549 TopSitesFactory::GetForProfile(profile_); |
| 540 if (top_sites) { | 550 if (top_sites) { |
| 541 top_sites->GetMostVisitedURLs( | 551 top_sites->GetMostVisitedURLs( |
| 542 base::Bind(&JumpList::OnMostVisitedURLsAvailable, | 552 base::Bind(&JumpList::OnMostVisitedURLsAvailable, |
| 543 weak_ptr_factory_.GetWeakPtr()), | 553 weak_ptr_factory_.GetWeakPtr()), |
| 544 false); | 554 false); |
| 545 } | 555 } |
| 546 } | 556 } |
| 547 | 557 |
| 548 void JumpList::DeferredTabRestoreServiceChanged() { | 558 void JumpList::DeferredTabRestoreServiceChanged() { |
| 559 DCHECK(CalledOnValidThread()); |
| 560 |
| 549 if (updates_to_skip_ > 0) { | 561 if (updates_to_skip_ > 0) { |
| 550 --updates_to_skip_; | 562 --updates_to_skip_; |
| 551 return; | 563 return; |
| 552 } | 564 } |
| 553 | 565 |
| 566 // Force a TopSite history sync when closing a first tab in one session. |
| 567 if (!has_tab_closed_) { |
| 568 has_tab_closed_ = true; |
| 569 scoped_refptr<history::TopSites> top_sites = |
| 570 TopSitesFactory::GetForProfile(profile_); |
| 571 if (top_sites) |
| 572 top_sites->SyncWithHistory(); |
| 573 } |
| 574 |
| 554 // Create a list of ShellLinkItems from the "Recently Closed" pages. | 575 // Create a list of ShellLinkItems from the "Recently Closed" pages. |
| 555 // As noted above, we create a ShellLinkItem objects with the following | 576 // As noted above, we create a ShellLinkItem objects with the following |
| 556 // parameters. | 577 // parameters. |
| 557 // * arguments | 578 // * arguments |
| 558 // The last URL of the tab object. | 579 // The last URL of the tab object. |
| 559 // * title | 580 // * title |
| 560 // The title of the last URL. | 581 // The title of the last URL. |
| 561 // * icon | 582 // * icon |
| 562 // An empty string. This value is to be updated in OnFaviconDataAvailable(). | 583 // An empty string. This value is to be updated in OnFaviconDataAvailable(). |
| 563 const int kRecentlyClosedCount = 3; | 584 |
| 564 sessions::TabRestoreService* tab_restore_service = | 585 sessions::TabRestoreService* tab_restore_service = |
| 565 TabRestoreServiceFactory::GetForProfile(profile_); | 586 TabRestoreServiceFactory::GetForProfile(profile_); |
| 566 | 587 |
| 567 { | 588 { |
| 568 JumpListData* data = &jumplist_data_->data; | 589 JumpListData* data = &jumplist_data_->data; |
| 569 base::AutoLock auto_lock(data->list_lock_); | 590 base::AutoLock auto_lock(data->list_lock_); |
| 570 data->recently_closed_pages_.clear(); | 591 data->recently_closed_pages_.clear(); |
| 571 | 592 |
| 572 for (const auto& entry : tab_restore_service->entries()) { | 593 for (const auto& entry : tab_restore_service->entries()) { |
| 573 if (data->recently_closed_pages_.size() >= kRecentlyClosedCount) | 594 if (data->recently_closed_pages_.size() >= kRecentlyClosedItems) |
| 574 break; | 595 break; |
| 575 switch (entry->type) { | 596 switch (entry->type) { |
| 576 case sessions::TabRestoreService::TAB: | 597 case sessions::TabRestoreService::TAB: |
| 577 AddTab(static_cast<const sessions::TabRestoreService::Tab&>(*entry), | 598 AddTab(static_cast<const sessions::TabRestoreService::Tab&>(*entry), |
| 578 kRecentlyClosedCount, data); | 599 kRecentlyClosedItems, data); |
| 579 break; | 600 break; |
| 580 case sessions::TabRestoreService::WINDOW: | 601 case sessions::TabRestoreService::WINDOW: |
| 581 AddWindow( | 602 AddWindow( |
| 582 static_cast<const sessions::TabRestoreService::Window&>(*entry), | 603 static_cast<const sessions::TabRestoreService::Window&>(*entry), |
| 583 kRecentlyClosedCount, data); | 604 kRecentlyClosedItems, data); |
| 584 break; | 605 break; |
| 585 } | 606 } |
| 586 } | 607 } |
| 587 | 608 |
| 588 data->recently_closed_pages_have_updates_ = true; | 609 data->recently_closed_pages_have_updates_ = true; |
| 589 } | 610 } |
| 590 | 611 |
| 591 // Send a query that retrieves the first favicon. | 612 // Send a query that retrieves the first favicon. |
| 592 StartLoadingFavicon(); | 613 StartLoadingFavicon(); |
| 593 } | 614 } |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 | 725 |
| 705 // Discard this JumpList update if JumpListUpdater::BeginUpdate takes longer | 726 // Discard this JumpList update if JumpListUpdater::BeginUpdate takes longer |
| 706 // than the maximum allowed time, as it's very likely the following update | 727 // than the maximum allowed time, as it's very likely the following update |
| 707 // steps will also take a long time. As we've not updated the icons on the | 728 // steps will also take a long time. As we've not updated the icons on the |
| 708 // disk, discarding this update wont't affect the current JumpList used by OS. | 729 // disk, discarding this update wont't affect the current JumpList used by OS. |
| 709 if (begin_update_timer.Elapsed() >= kTimeOutForJumplistBeginUpdate) { | 730 if (begin_update_timer.Elapsed() >= kTimeOutForJumplistBeginUpdate) { |
| 710 updates_to_skip_ = kUpdatesToSkipUnderHeavyLoad; | 731 updates_to_skip_ = kUpdatesToSkipUnderHeavyLoad; |
| 711 return false; | 732 return false; |
| 712 } | 733 } |
| 713 | 734 |
| 714 // The default maximum number of items to display in JumpList is 10. | |
| 715 // https://msdn.microsoft.com/library/windows/desktop/dd378398.aspx | |
| 716 // The "Most visited" category title always takes 1 of the JumpList slots if | |
| 717 // |most_visited_pages| isn't empty. | |
| 718 // The "Recently closed" category title will also take 1 if | |
| 719 // |recently_closed_pages| isn't empty. | |
| 720 // For the remaining slots, we allocate 5/8 (i.e., 5 slots if both categories | |
| 721 // present) to "most-visited" items and 3/8 (i.e., 3 slots if both categories | |
| 722 // present) to "recently-closed" items, respectively. | |
| 723 // Nevertheless, if there are not so many items in |recently_closed_pages|, | |
| 724 // we give the remaining slots to "most-visited" items. | |
| 725 | |
| 726 const int kMostVisited = 50; | |
| 727 const int kRecentlyClosed = 30; | |
| 728 const int kTotal = kMostVisited + kRecentlyClosed; | |
| 729 | |
| 730 // Adjust the available jumplist slots to account for the category titles. | |
| 731 size_t user_max_items_adjusted = jumplist_updater.user_max_items(); | |
| 732 if (!most_visited_pages.empty()) | |
| 733 --user_max_items_adjusted; | |
| 734 if (!recently_closed_pages.empty()) | |
| 735 --user_max_items_adjusted; | |
| 736 | |
| 737 size_t most_visited_items = | |
| 738 MulDiv(user_max_items_adjusted, kMostVisited, kTotal); | |
| 739 size_t recently_closed_items = user_max_items_adjusted - most_visited_items; | |
| 740 if (recently_closed_pages.size() < recently_closed_items) { | |
| 741 most_visited_items += recently_closed_items - recently_closed_pages.size(); | |
| 742 recently_closed_items = recently_closed_pages.size(); | |
| 743 } | |
| 744 | |
| 745 // Record the desired number of icons to create in this JumpList update. | 735 // Record the desired number of icons to create in this JumpList update. |
| 746 int icons_to_create = 0; | 736 int icons_to_create = 0; |
| 747 | 737 |
| 748 // Update the icons for "Most Visisted" category of the JumpList if needed. | 738 // Update the icons for "Most Visisted" category of the JumpList if needed. |
| 749 if (most_visited_pages_have_updates) { | 739 if (most_visited_pages_have_updates) { |
| 750 base::FilePath icon_dir_most_visited = GenerateJumplistIconDirName( | 740 base::FilePath icon_dir_most_visited = GenerateJumplistIconDirName( |
| 751 profile_dir, FILE_PATH_LITERAL("MostVisited")); | 741 profile_dir, FILE_PATH_LITERAL("MostVisited")); |
| 752 | 742 |
| 753 UpdateIconFiles(icon_dir_most_visited, most_visited_pages, | 743 UpdateIconFiles(icon_dir_most_visited, most_visited_pages, |
| 754 most_visited_items, JumpListCategory::kMostVisited); | 744 kMostVisitedItems, JumpListCategory::kMostVisited); |
| 755 | 745 |
| 756 icons_to_create += std::min(most_visited_pages.size(), most_visited_items); | 746 icons_to_create += std::min(most_visited_pages.size(), kMostVisitedItems); |
| 757 } | 747 } |
| 758 | 748 |
| 759 // Update the icons for "Recently Closed" category of the JumpList if needed. | 749 // Update the icons for "Recently Closed" category of the JumpList if needed. |
| 760 if (recently_closed_pages_have_updates) { | 750 if (recently_closed_pages_have_updates) { |
| 761 base::FilePath icon_dir_recent_closed = GenerateJumplistIconDirName( | 751 base::FilePath icon_dir_recent_closed = GenerateJumplistIconDirName( |
| 762 profile_dir, FILE_PATH_LITERAL("RecentClosed")); | 752 profile_dir, FILE_PATH_LITERAL("RecentClosed")); |
| 763 | 753 |
| 764 UpdateIconFiles(icon_dir_recent_closed, recently_closed_pages, | 754 UpdateIconFiles(icon_dir_recent_closed, recently_closed_pages, |
| 765 recently_closed_items, JumpListCategory::kRecentlyClosed); | 755 kRecentlyClosedItems, JumpListCategory::kRecentlyClosed); |
| 766 | 756 |
| 767 icons_to_create += | 757 icons_to_create += |
| 768 std::min(recently_closed_pages.size(), recently_closed_items); | 758 std::min(recently_closed_pages.size(), kRecentlyClosedItems); |
| 769 } | 759 } |
| 770 | 760 |
| 771 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. | 761 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. |
| 772 UMA_HISTOGRAM_COUNTS_100("WinJumplist.CreateIconFilesCount", icons_to_create); | 762 UMA_HISTOGRAM_COUNTS_100("WinJumplist.CreateIconFilesCount", icons_to_create); |
| 773 | 763 |
| 774 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. | 764 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. |
| 775 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.UpdateJumpListDuration"); | 765 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.UpdateJumpListDuration"); |
| 776 | 766 |
| 777 base::ElapsedTimer add_custom_category_timer; | 767 base::ElapsedTimer add_custom_category_timer; |
| 778 | 768 |
| 779 // Update the "Most Visited" category of the JumpList if it exists. | 769 // Update the "Most Visited" category of the JumpList if it exists. |
| 780 // This update request is applied into the JumpList when we commit this | 770 // This update request is applied into the JumpList when we commit this |
| 781 // transaction. | 771 // transaction. |
| 782 if (!jumplist_updater.AddCustomCategory( | 772 if (!jumplist_updater.AddCustomCategory( |
| 783 l10n_util::GetStringUTF16(IDS_NEW_TAB_MOST_VISITED), | 773 l10n_util::GetStringUTF16(IDS_NEW_TAB_MOST_VISITED), |
| 784 most_visited_pages, most_visited_items)) { | 774 most_visited_pages, kMostVisitedItems)) { |
| 785 return false; | 775 return false; |
| 786 } | 776 } |
| 787 | 777 |
| 788 // Update the "Recently Closed" category of the JumpList. | 778 // Update the "Recently Closed" category of the JumpList. |
| 789 if (!jumplist_updater.AddCustomCategory( | 779 if (!jumplist_updater.AddCustomCategory( |
| 790 l10n_util::GetStringUTF16(IDS_RECENTLY_CLOSED), recently_closed_pages, | 780 l10n_util::GetStringUTF16(IDS_RECENTLY_CLOSED), recently_closed_pages, |
| 791 recently_closed_items)) { | 781 kRecentlyClosedItems)) { |
| 792 return false; | 782 return false; |
| 793 } | 783 } |
| 794 | 784 |
| 795 // If JumpListUpdater::AddCustomCategory or JumpListUpdater::CommitUpdate | 785 // If JumpListUpdater::AddCustomCategory or JumpListUpdater::CommitUpdate |
| 796 // takes longer than the maximum allowed time, skip the next | 786 // takes longer than the maximum allowed time, skip the next |
| 797 // |kUpdatesToSkipUnderHeavyLoad| updates. This update should be finished | 787 // |kUpdatesToSkipUnderHeavyLoad| updates. This update should be finished |
| 798 // because we've already updated the icons on the disk. If discarding this | 788 // because we've already updated the icons on the disk. If discarding this |
| 799 // update from here, some items in the current JumpList may not have icons | 789 // update from here, some items in the current JumpList may not have icons |
| 800 // as they've been delete from the disk. In this case, the background color of | 790 // as they've been delete from the disk. In this case, the background color of |
| 801 // the JumpList panel is used instead, which doesn't look nice. | 791 // the JumpList panel is used instead, which doesn't look nice. |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 859 app_id, profile_dir, local_most_visited_pages, | 849 app_id, profile_dir, local_most_visited_pages, |
| 860 local_recently_closed_pages, most_visited_pages_have_updates, | 850 local_recently_closed_pages, most_visited_pages_have_updates, |
| 861 recently_closed_pages_have_updates, incognito_availability)) { | 851 recently_closed_pages_have_updates, incognito_availability)) { |
| 862 base::AutoLock auto_lock(data->list_lock_); | 852 base::AutoLock auto_lock(data->list_lock_); |
| 863 if (most_visited_pages_have_updates) | 853 if (most_visited_pages_have_updates) |
| 864 data->most_visited_pages_have_updates_ = true; | 854 data->most_visited_pages_have_updates_ = true; |
| 865 if (recently_closed_pages_have_updates) | 855 if (recently_closed_pages_have_updates) |
| 866 data->recently_closed_pages_have_updates_ = true; | 856 data->recently_closed_pages_have_updates_ = true; |
| 867 } | 857 } |
| 868 } | 858 } |
| OLD | NEW |