Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(269)

Side by Side Diff: chrome/browser/win/jumplist.cc

Issue 2865133003: Defer syncing TopSites with history until the first tab closure (Closed)
Patch Set: Delay the history sync until 3 tabs are closed rather than 3 recently closed category updates are scheduled Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/win/jumplist.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 #include "ui/gfx/image/image_family.h" 48 #include "ui/gfx/image/image_family.h"
49 #include "ui/gfx/image/image_skia.h" 49 #include "ui/gfx/image/image_skia.h"
50 #include "ui/gfx/image/image_skia_rep.h" 50 #include "ui/gfx/image/image_skia_rep.h"
51 #include "url/gurl.h" 51 #include "url/gurl.h"
52 52
53 using content::BrowserThread; 53 using content::BrowserThread;
54 using JumpListData = JumpList::JumpListData; 54 using JumpListData = JumpList::JumpListData;
55 55
56 namespace { 56 namespace {
57 57
58 // JumpList "Most Visited" category is forced to sync with the TopSites service
59 // only after this number of tabs are closed after Chrome launches.
60 constexpr int kTabClosedCountToDelayTopSitesSync = 3;
61
58 // The delay before updating the JumpList to prevent update storms. 62 // The delay before updating the JumpList to prevent update storms.
59 constexpr base::TimeDelta kDelayForJumplistUpdate = 63 constexpr base::TimeDelta kDelayForJumplistUpdate =
60 base::TimeDelta::FromMilliseconds(3500); 64 base::TimeDelta::FromMilliseconds(3500);
61 65
62 // The maximum allowed time for JumpListUpdater::BeginUpdate. Updates taking 66 // The maximum allowed time for JumpListUpdater::BeginUpdate. Updates taking
63 // longer than this are discarded to prevent bogging down slow machines. 67 // longer than this are discarded to prevent bogging down slow machines.
64 constexpr base::TimeDelta kTimeOutForJumplistUpdate = 68 constexpr base::TimeDelta kTimeOutForJumplistUpdate =
65 base::TimeDelta::FromMilliseconds(500); 69 base::TimeDelta::FromMilliseconds(500);
66 70
67 // Appends the common switches to each shell link. 71 // Appends the common switches to each shell link.
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 } // namespace 178 } // namespace
175 179
176 JumpList::JumpListData::JumpListData() {} 180 JumpList::JumpListData::JumpListData() {}
177 181
178 JumpList::JumpListData::~JumpListData() {} 182 JumpList::JumpListData::~JumpListData() {}
179 183
180 JumpList::JumpList(Profile* profile) 184 JumpList::JumpList(Profile* profile)
181 : RefcountedKeyedService(content::BrowserThread::GetTaskRunnerForThread( 185 : RefcountedKeyedService(content::BrowserThread::GetTaskRunnerForThread(
182 content::BrowserThread::UI)), 186 content::BrowserThread::UI)),
183 profile_(profile), 187 profile_(profile),
188 tab_closed_count_(0),
189 initial_most_visited_update_done_(false),
184 jumplist_data_(new base::RefCountedData<JumpListData>), 190 jumplist_data_(new base::RefCountedData<JumpListData>),
185 task_id_(base::CancelableTaskTracker::kBadTaskId), 191 task_id_(base::CancelableTaskTracker::kBadTaskId),
186 update_jumplist_task_runner_(base::CreateCOMSTATaskRunnerWithTraits( 192 update_jumplist_task_runner_(base::CreateCOMSTATaskRunnerWithTraits(
187 {base::MayBlock(), base::TaskPriority::USER_VISIBLE, 193 {base::MayBlock(), base::TaskPriority::USER_VISIBLE,
188 base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN})), 194 base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN})),
189 delete_jumplisticons_task_runner_( 195 delete_jumplisticons_task_runner_(
190 base::CreateSequencedTaskRunnerWithTraits( 196 base::CreateSequencedTaskRunnerWithTraits(
191 {base::MayBlock(), base::TaskPriority::BACKGROUND, 197 {base::MayBlock(), base::TaskPriority::BACKGROUND,
192 base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN})), 198 base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN})),
193 weak_ptr_factory_(this) { 199 weak_ptr_factory_(this) {
194 DCHECK(Enabled()); 200 DCHECK(Enabled());
195 // To update JumpList when a tab is added or removed, we add this object to 201 // To update JumpList when a tab is added or removed, we add this object to
196 // the observer list of the TabRestoreService class. 202 // the observer list of the TabRestoreService class.
197 // When we add this object to the observer list, we save the pointer to this 203 // When we add this object to the observer list, we save the pointer to this
198 // TabRestoreService object. This pointer is used when we remove this object 204 // TabRestoreService object. This pointer is used when we remove this object
199 // from the observer list. 205 // from the observer list.
200 sessions::TabRestoreService* tab_restore_service = 206 sessions::TabRestoreService* tab_restore_service =
201 TabRestoreServiceFactory::GetForProfile(profile_); 207 TabRestoreServiceFactory::GetForProfile(profile_);
202 if (!tab_restore_service) 208 if (!tab_restore_service)
203 return; 209 return;
204 210
205 app_id_ = 211 app_id_ =
206 shell_integration::win::GetChromiumModelIdForProfile(profile_->GetPath()); 212 shell_integration::win::GetChromiumModelIdForProfile(profile_->GetPath());
207 213
208 scoped_refptr<history::TopSites> top_sites = 214 scoped_refptr<history::TopSites> top_sites =
209 TopSitesFactory::GetForProfile(profile_); 215 TopSitesFactory::GetForProfile(profile_);
210 if (top_sites) { 216 if (top_sites) {
211 // TopSites updates itself after a delay. This is especially noticable when
212 // your profile is empty. Ask TopSites to update itself when jumplist is
213 // initialized.
214 top_sites->SyncWithHistory();
215 // Register as TopSitesObserver so that we can update ourselves when the 217 // Register as TopSitesObserver so that we can update ourselves when the
216 // TopSites changes. 218 // TopSites changes. TopSites updates itself after a delay. This is
219 // especially noticable when your profile is empty.
217 top_sites->AddObserver(this); 220 top_sites->AddObserver(this);
218 } 221 }
219 tab_restore_service->AddObserver(this); 222 tab_restore_service->AddObserver(this);
220 pref_change_registrar_.reset(new PrefChangeRegistrar); 223 pref_change_registrar_.reset(new PrefChangeRegistrar);
221 pref_change_registrar_->Init(profile_->GetPrefs()); 224 pref_change_registrar_->Init(profile_->GetPrefs());
222 pref_change_registrar_->Add( 225 pref_change_registrar_->Add(
223 prefs::kIncognitoModeAvailability, 226 prefs::kIncognitoModeAvailability,
224 base::Bind(&JumpList::OnIncognitoAvailabilityChanged, this)); 227 base::Bind(&JumpList::OnIncognitoAvailabilityChanged, this));
225 } 228 }
226 229
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 266
264 void JumpList::ShutdownOnUIThread() { 267 void JumpList::ShutdownOnUIThread() {
265 DCHECK(CalledOnValidThread()); 268 DCHECK(CalledOnValidThread());
266 Terminate(); 269 Terminate();
267 } 270 }
268 271
269 void JumpList::OnMostVisitedURLsAvailable( 272 void JumpList::OnMostVisitedURLsAvailable(
270 const history::MostVisitedURLList& urls) { 273 const history::MostVisitedURLList& urls) {
271 DCHECK(CalledOnValidThread()); 274 DCHECK(CalledOnValidThread());
272 275
273 // At most 9 JumpList items can be displayed for the "Most Visited" 276 // At most 5 JumpList items can be displayed for the "Most Visited"
274 // category. 277 // category.
275 const int kMostVistedCount = 9; 278 const int kMostVistedCount = 5;
276 { 279 {
277 JumpListData* data = &jumplist_data_->data; 280 JumpListData* data = &jumplist_data_->data;
278 base::AutoLock auto_lock(data->list_lock_); 281 base::AutoLock auto_lock(data->list_lock_);
279 data->most_visited_pages_.clear(); 282 data->most_visited_pages_.clear();
280 283
281 for (size_t i = 0; i < urls.size() && i < kMostVistedCount; i++) { 284 for (size_t i = 0; i < urls.size() && i < kMostVistedCount; i++) {
282 const history::MostVisitedURL& url = urls[i]; 285 const history::MostVisitedURL& url = urls[i];
283 scoped_refptr<ShellLinkItem> link = CreateShellLink(); 286 scoped_refptr<ShellLinkItem> link = CreateShellLink();
284 std::string url_string = url.url.spec(); 287 std::string url_string = url.url.spec();
285 base::string16 url_string_wide = base::UTF8ToUTF16(url_string); 288 base::string16 url_string_wide = base::UTF8ToUTF16(url_string);
(...skipping 10 matching lines...) Expand all
296 // Send a query that retrieves the first favicon. 299 // Send a query that retrieves the first favicon.
297 StartLoadingFavicon(); 300 StartLoadingFavicon();
298 } 301 }
299 302
300 void JumpList::TabRestoreServiceChanged(sessions::TabRestoreService* service) { 303 void JumpList::TabRestoreServiceChanged(sessions::TabRestoreService* service) {
301 DCHECK(CalledOnValidThread()); 304 DCHECK(CalledOnValidThread());
302 305
303 // if we have a pending favicon request, cancel it here (it is out of date). 306 // if we have a pending favicon request, cancel it here (it is out of date).
304 CancelPendingUpdate(); 307 CancelPendingUpdate();
305 308
309 ++tab_closed_count_;
310
306 // Initialize the one-shot timer to update the the "Recently Closed" category 311 // Initialize the one-shot timer to update the the "Recently Closed" category
307 // in a while. If there is already a request queued then cancel it and post 312 // in a while. If there is already a request queued then cancel it and post
308 // the new request. This ensures that JumpList update of the "Recently Closed" 313 // the new request. This ensures that JumpList update of the "Recently Closed"
309 // category won't happen until there has been a brief quiet period, thus 314 // category won't happen until there has been a brief quiet period, thus
310 // avoiding update storms. 315 // avoiding update storms.
311 if (timer_recently_closed_.IsRunning()) { 316 if (timer_recently_closed_.IsRunning()) {
312 timer_recently_closed_.Reset(); 317 timer_recently_closed_.Reset();
313 } else { 318 } else {
314 timer_recently_closed_.Start( 319 timer_recently_closed_.Start(
315 FROM_HERE, kDelayForJumplistUpdate, 320 FROM_HERE, kDelayForJumplistUpdate,
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 if (timer_most_visited_.IsRunning()) { 512 if (timer_most_visited_.IsRunning()) {
508 timer_most_visited_.Reset(); 513 timer_most_visited_.Reset();
509 } else { 514 } else {
510 timer_most_visited_.Start( 515 timer_most_visited_.Start(
511 FROM_HERE, kDelayForJumplistUpdate, 516 FROM_HERE, kDelayForJumplistUpdate,
512 base::Bind(&JumpList::DeferredTopSitesChanged, base::Unretained(this))); 517 base::Bind(&JumpList::DeferredTopSitesChanged, base::Unretained(this)));
513 } 518 }
514 } 519 }
515 520
516 void JumpList::DeferredTopSitesChanged() { 521 void JumpList::DeferredTopSitesChanged() {
522 if (tab_closed_count_ < kTabClosedCountToDelayTopSitesSync)
523 return;
524
517 scoped_refptr<history::TopSites> top_sites = 525 scoped_refptr<history::TopSites> top_sites =
518 TopSitesFactory::GetForProfile(profile_); 526 TopSitesFactory::GetForProfile(profile_);
519 if (top_sites) { 527 if (top_sites) {
520 top_sites->GetMostVisitedURLs( 528 top_sites->GetMostVisitedURLs(
521 base::Bind(&JumpList::OnMostVisitedURLsAvailable, 529 base::Bind(&JumpList::OnMostVisitedURLsAvailable,
522 weak_ptr_factory_.GetWeakPtr()), 530 weak_ptr_factory_.GetWeakPtr()),
523 false); 531 false);
524 } 532 }
525 } 533 }
526 534
527 void JumpList::DeferredTabRestoreServiceChanged() { 535 void JumpList::DeferredTabRestoreServiceChanged() {
536 if (tab_closed_count_ < kTabClosedCountToDelayTopSitesSync) {
537 return;
538 } else if (!initial_most_visited_update_done_) {
539 scoped_refptr<history::TopSites> top_sites =
540 TopSitesFactory::GetForProfile(profile_);
541 if (top_sites) {
542 top_sites->SyncWithHistory();
543 }
544 initial_most_visited_update_done_ = true;
545 }
546
528 // Create a list of ShellLinkItems from the "Recently Closed" pages. 547 // Create a list of ShellLinkItems from the "Recently Closed" pages.
529 // As noted above, we create a ShellLinkItem objects with the following 548 // As noted above, we create a ShellLinkItem objects with the following
530 // parameters. 549 // parameters.
531 // * arguments 550 // * arguments
532 // The last URL of the tab object. 551 // The last URL of the tab object.
533 // * title 552 // * title
534 // The title of the last URL. 553 // The title of the last URL.
535 // * icon 554 // * icon
536 // An empty string. This value is to be updated in OnFaviconDataAvailable(). 555 // An empty string. This value is to be updated in OnFaviconDataAvailable().
537 const int kRecentlyClosedCount = 3; 556 const int kRecentlyClosedCount = 3;
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 // For the remaining slots, we allocate 5/8 (i.e., 5 slots if both categories 642 // For the remaining slots, we allocate 5/8 (i.e., 5 slots if both categories
624 // present) to "most-visited" items and 3/8 (i.e., 3 slots if both categories 643 // present) to "most-visited" items and 3/8 (i.e., 3 slots if both categories
625 // present) to "recently-closed" items, respectively. 644 // present) to "recently-closed" items, respectively.
626 // Nevertheless, if there are not so many items in |recently_closed_pages|, 645 // Nevertheless, if there are not so many items in |recently_closed_pages|,
627 // we give the remaining slots to "most-visited" items. 646 // we give the remaining slots to "most-visited" items.
628 647
629 const int kMostVisited = 50; 648 const int kMostVisited = 50;
630 const int kRecentlyClosed = 30; 649 const int kRecentlyClosed = 30;
631 const int kTotal = kMostVisited + kRecentlyClosed; 650 const int kTotal = kMostVisited + kRecentlyClosed;
632 651
633 // Adjust the available jumplist slots to account for the category titles. 652 // Adjust the available jumplist slots to account for the two category titles.
634 size_t user_max_items_adjusted = jumplist_updater.user_max_items(); 653 size_t user_max_items_adjusted = jumplist_updater.user_max_items() - 2;
635 if (!most_visited_pages.empty())
636 --user_max_items_adjusted;
637 if (!recently_closed_pages.empty())
638 --user_max_items_adjusted;
639 654
640 size_t most_visited_items = 655 size_t most_visited_items =
641 MulDiv(user_max_items_adjusted, kMostVisited, kTotal); 656 MulDiv(user_max_items_adjusted, kMostVisited, kTotal);
gab 2017/05/12 18:13:35 Can we just make this 5 and recently closed 3. i.e
chengx 2017/05/18 00:51:00 I stopped load-balancing, and limited these two ca
642 size_t recently_closed_items = user_max_items_adjusted - most_visited_items; 657 size_t recently_closed_items = user_max_items_adjusted - most_visited_items;
643 if (recently_closed_pages.size() < recently_closed_items) {
644 most_visited_items += recently_closed_items - recently_closed_pages.size();
645 recently_closed_items = recently_closed_pages.size();
646 }
647 658
648 // Record the desired number of icons to create in this JumpList update. 659 // Record the desired number of icons to create in this JumpList update.
649 int icons_to_create = 0; 660 int icons_to_create = 0;
650 661
651 // Update the icons for "Most Visisted" category of the JumpList if needed. 662 // Update the icons for "Most Visisted" category of the JumpList if needed.
652 if (most_visited_pages_have_updates) { 663 if (most_visited_pages_have_updates) {
653 base::FilePath icon_dir_most_visited = GenerateJumplistIconDirName( 664 base::FilePath icon_dir_most_visited = GenerateJumplistIconDirName(
654 profile_dir, FILE_PATH_LITERAL("MostVisited")); 665 profile_dir, FILE_PATH_LITERAL("MostVisited"));
655 666
656 UpdateIconFiles(icon_dir_most_visited, most_visited_pages, 667 UpdateIconFiles(icon_dir_most_visited, most_visited_pages,
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 app_id, profile_dir, local_most_visited_pages, 753 app_id, profile_dir, local_most_visited_pages,
743 local_recently_closed_pages, most_visited_pages_have_updates, 754 local_recently_closed_pages, most_visited_pages_have_updates,
744 recently_closed_pages_have_updates, incognito_availability)) { 755 recently_closed_pages_have_updates, incognito_availability)) {
745 base::AutoLock auto_lock(data->list_lock_); 756 base::AutoLock auto_lock(data->list_lock_);
746 if (most_visited_pages_have_updates) 757 if (most_visited_pages_have_updates)
747 data->most_visited_pages_have_updates_ = true; 758 data->most_visited_pages_have_updates_ = true;
748 if (recently_closed_pages_have_updates) 759 if (recently_closed_pages_have_updates)
749 data->recently_closed_pages_have_updates_ = true; 760 data->recently_closed_pages_have_updates_ = true;
750 } 761 }
751 } 762 }
OLDNEW
« no previous file with comments | « chrome/browser/win/jumplist.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698