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

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

Issue 2940743002: Reorder the methods in JumpList class according to the update workflow (Closed)
Patch Set: fix the order of two methods Created 3 years, 6 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
« chrome/browser/win/jumplist.h ('K') | « 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 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 prefs::kIncognitoModeAvailability, 243 prefs::kIncognitoModeAvailability,
244 base::Bind(&JumpList::OnIncognitoAvailabilityChanged, 244 base::Bind(&JumpList::OnIncognitoAvailabilityChanged,
245 base::Unretained(this))); 245 base::Unretained(this)));
246 } 246 }
247 247
248 JumpList::~JumpList() { 248 JumpList::~JumpList() {
249 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 249 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
250 Terminate(); 250 Terminate();
251 } 251 }
252 252
253 void JumpList::Shutdown() {
grt (UTC plus 2) 2017/06/14 20:50:38 please move up to line 201
chengx 2017/06/16 18:10:41 Done.
254 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
255 Terminate();
256 }
257
253 // static 258 // static
254 bool JumpList::Enabled() { 259 bool JumpList::Enabled() {
255 return JumpListUpdater::IsEnabled(); 260 return JumpListUpdater::IsEnabled();
256 } 261 }
257 262
258 void JumpList::CancelPendingUpdate() { 263 void JumpList::TopSitesLoaded(history::TopSites* top_sites) {}
264
265 void JumpList::TopSitesChanged(history::TopSites* top_sites,
266 ChangeReason change_reason) {
259 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 267 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
260 268
261 // Cancel a pending most-visited URL fetch by invalidating the weak pointer. 269 top_sites_has_pending_notification_ = true;
262 weak_ptr_factory_.InvalidateWeakPtrs();
263 270
264 // Cancel a pending favicon loading by invalidating its task id. 271 // Postpone handling this notification until a pending update completes.
265 if (task_id_ != base::CancelableTaskTracker::kBadTaskId) { 272 if (update_in_progress_)
266 cancelable_task_tracker_.TryCancel(task_id_); 273 return;
267 task_id_ = base::CancelableTaskTracker::kBadTaskId; 274
275 // If we have a pending favicon request, cancel it here as it's out of date.
276 CancelPendingUpdate();
277
278 // Initialize the one-shot timer to update the JumpList in a while.
279 InitializeTimerForUpdate();
280 }
281
282 void JumpList::TabRestoreServiceChanged(sessions::TabRestoreService* service) {
283 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
284
285 tab_restore_has_pending_notification_ = true;
286
287 // Postpone handling this notification until a pending update completes.
288 if (update_in_progress_)
289 return;
290
291 // if we have a pending favicon request, cancel it here as it's out of date.
292 CancelPendingUpdate();
293
294 // Initialize the one-shot timer to update the JumpList in a while.
295 InitializeTimerForUpdate();
296 }
297
298 void JumpList::TabRestoreServiceDestroyed(
299 sessions::TabRestoreService* service) {}
300
301 void JumpList::InitializeTimerForUpdate() {
302 if (timer_.IsRunning()) {
303 timer_.Reset();
304 } else {
305 // base::Unretained is safe since |this| is guaranteed to outlive timer_.
306 timer_.Start(FROM_HERE, kDelayForJumplistUpdate,
307 base::Bind(&JumpList::OnDelayTimer, base::Unretained(this)));
268 } 308 }
269 } 309 }
270 310
271 void JumpList::Terminate() { 311 void JumpList::OnDelayTimer() {
272 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 312 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
273 timer_.Stop(); 313
274 CancelPendingUpdate(); 314 if (updates_to_skip_ > 0) {
275 update_in_progress_ = false; 315 --updates_to_skip_;
276 if (profile_) { 316 return;
277 sessions::TabRestoreService* tab_restore_service = 317 }
278 TabRestoreServiceFactory::GetForProfile(profile_); 318
279 if (tab_restore_service) 319 // Retrieve the recently closed URLs synchronously.
280 tab_restore_service->RemoveObserver(this); 320 if (tab_restore_has_pending_notification_) {
321 tab_restore_has_pending_notification_ = false;
322 ProcessTabRestoreServiceNotification();
323 }
324
325 // If TopSites has updates, retrieve the URLs asynchronously, and on its
326 // completion, trigger favicon loading.
327 // Otherwise, call StartLoadingFavicon directly to start favicon loading.
328 if (top_sites_has_pending_notification_)
329 ProcessTopSitesNotification();
330 else
331 StartLoadingFavicon();
332 }
333
334 void JumpList::ProcessTopSitesNotification() {
335 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
336
337 // Opening the first tab in one session triggers a TopSite history sync.
338 // Delay this sync till the first tab is closed to allow the "recently closed"
339 // category from last session to stay longer. All previous pending
340 // notifications from TopSites are ignored.
341 if (!has_tab_closed_) {
342 top_sites_has_pending_notification_ = false;
343 return;
344 }
345
346 scoped_refptr<history::TopSites> top_sites =
347 TopSitesFactory::GetForProfile(profile_);
348 if (top_sites) {
349 top_sites->GetMostVisitedURLs(
350 base::Bind(&JumpList::OnMostVisitedURLsAvailable,
351 weak_ptr_factory_.GetWeakPtr()),
352 false);
353 }
354 }
355
356 void JumpList::ProcessTabRestoreServiceNotification() {
357 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
358
359 // Create a list of ShellLinkItems from the "Recently Closed" pages.
360 // As noted above, we create a ShellLinkItem objects with the following
361 // parameters.
362 // * arguments
363 // The last URL of the tab object.
364 // * title
365 // The title of the last URL.
366 // * icon
367 // An empty string. This value is to be updated in OnFaviconDataAvailable().
368
369 sessions::TabRestoreService* tab_restore_service =
370 TabRestoreServiceFactory::GetForProfile(profile_);
371
372 recently_closed_pages_.clear();
373
374 for (const auto& entry : tab_restore_service->entries()) {
375 if (recently_closed_pages_.size() >= kRecentlyClosedItems)
376 break;
377 switch (entry->type) {
378 case sessions::TabRestoreService::TAB:
379 AddTab(static_cast<const sessions::TabRestoreService::Tab&>(*entry),
380 kRecentlyClosedItems);
381 break;
382 case sessions::TabRestoreService::WINDOW:
383 AddWindow(
384 static_cast<const sessions::TabRestoreService::Window&>(*entry),
385 kRecentlyClosedItems);
386 break;
387 }
388 }
389
390 recently_closed_should_update_ = true;
391
392 // Force a TopSite history sync when closing a first tab in one session.
393 if (!has_tab_closed_) {
394 has_tab_closed_ = true;
281 scoped_refptr<history::TopSites> top_sites = 395 scoped_refptr<history::TopSites> top_sites =
282 TopSitesFactory::GetForProfile(profile_); 396 TopSitesFactory::GetForProfile(profile_);
283 if (top_sites) 397 if (top_sites)
284 top_sites->RemoveObserver(this); 398 top_sites->SyncWithHistory();
285 pref_change_registrar_.reset();
286 } 399 }
287 profile_ = nullptr;
288 }
289
290 void JumpList::Shutdown() {
291 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
292 Terminate();
293 } 400 }
294 401
295 void JumpList::OnMostVisitedURLsAvailable( 402 void JumpList::OnMostVisitedURLsAvailable(
296 const history::MostVisitedURLList& urls) { 403 const history::MostVisitedURLList& urls) {
297 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 404 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
298 405
299 top_sites_has_pending_notification_ = false; 406 top_sites_has_pending_notification_ = false;
300 407
301 // There is no need to update the JumpList if the top most visited sites in 408 // There is no need to update the JumpList if the top most visited sites in
302 // display have not changed. 409 // display have not changed.
(...skipping 16 matching lines...) Expand all
319 most_visited_pages_.push_back(link); 426 most_visited_pages_.push_back(link);
320 icon_urls_.emplace_back(std::move(url_string), std::move(link)); 427 icon_urls_.emplace_back(std::move(url_string), std::move(link));
321 } 428 }
322 429
323 most_visited_should_update_ = true; 430 most_visited_should_update_ = true;
324 431
325 // Send a query that retrieves the first favicon. 432 // Send a query that retrieves the first favicon.
326 StartLoadingFavicon(); 433 StartLoadingFavicon();
327 } 434 }
328 435
329 void JumpList::TabRestoreServiceChanged(sessions::TabRestoreService* service) {
330 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
331
332 tab_restore_has_pending_notification_ = true;
333
334 // Postpone handling this notification until a pending update completes.
335 if (update_in_progress_)
336 return;
337
338 // if we have a pending favicon request, cancel it here as it's out of date.
339 CancelPendingUpdate();
340
341 // Initialize the one-shot timer to update the JumpList in a while.
342 InitializeTimerForUpdate();
343 }
344
345 void JumpList::TabRestoreServiceDestroyed(
346 sessions::TabRestoreService* service) {}
347
348 bool JumpList::AddTab(const sessions::TabRestoreService::Tab& tab, 436 bool JumpList::AddTab(const sessions::TabRestoreService::Tab& tab,
349 size_t max_items) { 437 size_t max_items) {
350 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 438 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
351 439
352 // This code adds the URL and the title strings of the given tab to the 440 // This code adds the URL and the title strings of the given tab to the
353 // JumpList variables. 441 // JumpList variables.
354 if (recently_closed_pages_.size() >= max_items) 442 if (recently_closed_pages_.size() >= max_items)
355 return false; 443 return false;
356 444
357 scoped_refptr<ShellLinkItem> link = CreateShellLink(); 445 scoped_refptr<ShellLinkItem> link = CreateShellLink();
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 local_most_visited_pages, local_recently_closed_pages, 566 local_most_visited_pages, local_recently_closed_pages,
479 most_visited_should_update, recently_closed_should_update, 567 most_visited_should_update, recently_closed_should_update,
480 incognito_availability, update_results.get()), 568 incognito_availability, update_results.get()),
481 base::Bind(&JumpList::OnRunUpdateCompletion, 569 base::Bind(&JumpList::OnRunUpdateCompletion,
482 weak_ptr_factory_.GetWeakPtr(), 570 weak_ptr_factory_.GetWeakPtr(),
483 base::Passed(std::move(update_results))))) { 571 base::Passed(std::move(update_results))))) {
484 OnRunUpdateCompletion(base::MakeUnique<UpdateResults>()); 572 OnRunUpdateCompletion(base::MakeUnique<UpdateResults>());
485 } 573 }
486 } 574 }
487 575
488 void JumpList::TopSitesLoaded(history::TopSites* top_sites) { 576 void JumpList::OnRunUpdateCompletion(
489 } 577 std::unique_ptr<UpdateResults> update_results) {
490
491 void JumpList::TopSitesChanged(history::TopSites* top_sites,
492 ChangeReason change_reason) {
493 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 578 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
494 579
495 top_sites_has_pending_notification_ = true; 580 // Update JumpList member variables based on the results from the update run
581 // just finished.
582 if (update_results->update_timeout)
583 updates_to_skip_ = kUpdatesToSkipUnderHeavyLoad;
496 584
497 // Postpone handling this notification until a pending update completes. 585 if (update_results->update_success) {
498 if (update_in_progress_) 586 most_visited_icons_.swap(update_results->most_visited_icons_in_update);
499 return; 587 recently_closed_icons_.swap(
588 update_results->recently_closed_icons_in_update);
589 most_visited_should_update_ = false;
590 recently_closed_should_update_ = false;
591 }
500 592
501 // If we have a pending favicon request, cancel it here as it's out of date. 593 update_in_progress_ = false;
502 CancelPendingUpdate();
503 594
504 // Initialize the one-shot timer to update the JumpList in a while. 595 // If there is any new notification during the update run just finished, start
505 InitializeTimerForUpdate(); 596 // another JumpList update.
506 } 597 // Otherwise, post tasks to delete the JumpListIcons and JumpListIconsOld
598 // folders as they are no longer needed. Now we have the
599 // JumpListIcons{MostVisited, RecentClosed} folders instead.
600 if (top_sites_has_pending_notification_ ||
601 tab_restore_has_pending_notification_) {
602 InitializeTimerForUpdate();
603 } else {
604 base::FilePath profile_dir = profile_->GetPath();
605 base::FilePath icon_dir =
606 GenerateJumplistIconDirName(profile_dir, FILE_PATH_LITERAL(""));
607 delete_jumplisticons_task_runner_->PostTask(
608 FROM_HERE,
609 base::Bind(&DeleteDirectory, std::move(icon_dir), kFileDeleteLimit));
507 610
508 void JumpList::InitializeTimerForUpdate() { 611 base::FilePath icon_dir_old =
509 if (timer_.IsRunning()) { 612 GenerateJumplistIconDirName(profile_dir, FILE_PATH_LITERAL("Old"));
510 timer_.Reset(); 613 delete_jumplisticons_task_runner_->PostTask(
511 } else { 614 FROM_HERE, base::Bind(&DeleteDirectory, std::move(icon_dir_old),
512 // base::Unretained is safe since |this| is guaranteed to outlive timer_. 615 kFileDeleteLimit));
513 timer_.Start(FROM_HERE, kDelayForJumplistUpdate,
514 base::Bind(&JumpList::OnDelayTimer, base::Unretained(this)));
515 } 616 }
516 } 617 }
517 618
518 void JumpList::OnDelayTimer() { 619 void JumpList::CancelPendingUpdate() {
519 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 620 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
520 621
521 if (updates_to_skip_ > 0) { 622 // Cancel a pending most-visited URL fetch by invalidating the weak pointer.
522 --updates_to_skip_; 623 weak_ptr_factory_.InvalidateWeakPtrs();
523 return;
524 }
525 624
526 // Retrieve the recently closed URLs synchronously. 625 // Cancel a pending favicon loading by invalidating its task id.
527 if (tab_restore_has_pending_notification_) { 626 if (task_id_ != base::CancelableTaskTracker::kBadTaskId) {
528 tab_restore_has_pending_notification_ = false; 627 cancelable_task_tracker_.TryCancel(task_id_);
529 ProcessTabRestoreServiceNotification(); 628 task_id_ = base::CancelableTaskTracker::kBadTaskId;
530 }
531
532 // If TopSites has updates, retrieve the URLs asynchronously, and on its
533 // completion, trigger favicon loading.
534 // Otherwise, call StartLoadingFavicon directly to start favicon loading.
535 if (top_sites_has_pending_notification_)
536 ProcessTopSitesNotification();
537 else
538 StartLoadingFavicon();
539 }
540
541 void JumpList::ProcessTopSitesNotification() {
542 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
543
544 // Opening the first tab in one session triggers a TopSite history sync.
545 // Delay this sync till the first tab is closed to allow the "recently closed"
546 // category from last session to stay longer. All previous pending
547 // notifications from TopSites are ignored.
548 if (!has_tab_closed_) {
549 top_sites_has_pending_notification_ = false;
550 return;
551 }
552
553 scoped_refptr<history::TopSites> top_sites =
554 TopSitesFactory::GetForProfile(profile_);
555 if (top_sites) {
556 top_sites->GetMostVisitedURLs(
557 base::Bind(&JumpList::OnMostVisitedURLsAvailable,
558 weak_ptr_factory_.GetWeakPtr()),
559 false);
560 } 629 }
561 } 630 }
562 631
563 void JumpList::ProcessTabRestoreServiceNotification() { 632 void JumpList::Terminate() {
564 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 633 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
565 634 timer_.Stop();
566 // Create a list of ShellLinkItems from the "Recently Closed" pages. 635 CancelPendingUpdate();
567 // As noted above, we create a ShellLinkItem objects with the following 636 update_in_progress_ = false;
568 // parameters. 637 if (profile_) {
569 // * arguments 638 sessions::TabRestoreService* tab_restore_service =
570 // The last URL of the tab object. 639 TabRestoreServiceFactory::GetForProfile(profile_);
571 // * title 640 if (tab_restore_service)
572 // The title of the last URL. 641 tab_restore_service->RemoveObserver(this);
573 // * icon
574 // An empty string. This value is to be updated in OnFaviconDataAvailable().
575
576 sessions::TabRestoreService* tab_restore_service =
577 TabRestoreServiceFactory::GetForProfile(profile_);
578
579 recently_closed_pages_.clear();
580
581 for (const auto& entry : tab_restore_service->entries()) {
582 if (recently_closed_pages_.size() >= kRecentlyClosedItems)
583 break;
584 switch (entry->type) {
585 case sessions::TabRestoreService::TAB:
586 AddTab(static_cast<const sessions::TabRestoreService::Tab&>(*entry),
587 kRecentlyClosedItems);
588 break;
589 case sessions::TabRestoreService::WINDOW:
590 AddWindow(
591 static_cast<const sessions::TabRestoreService::Window&>(*entry),
592 kRecentlyClosedItems);
593 break;
594 }
595 }
596
597 recently_closed_should_update_ = true;
598
599 // Force a TopSite history sync when closing a first tab in one session.
600 if (!has_tab_closed_) {
601 has_tab_closed_ = true;
602 scoped_refptr<history::TopSites> top_sites = 642 scoped_refptr<history::TopSites> top_sites =
603 TopSitesFactory::GetForProfile(profile_); 643 TopSitesFactory::GetForProfile(profile_);
604 if (top_sites) 644 if (top_sites)
605 top_sites->SyncWithHistory(); 645 top_sites->RemoveObserver(this);
646 pref_change_registrar_.reset();
606 } 647 }
648 profile_ = nullptr;
607 } 649 }
608 650
609 // static 651 // static
610 void JumpList::DeleteIconFiles(const base::FilePath& icon_dir,
611 URLIconCache* icon_cache) {
612 // Put all cached icon file paths into a set.
613 base::flat_set<base::FilePath> cached_files;
614 cached_files.reserve(icon_cache->size());
615
616 for (const auto& url_path_pair : *icon_cache)
617 cached_files.insert(url_path_pair.second);
618
619 DeleteNonCachedFiles(icon_dir, cached_files);
620 }
621
622 // static
623 int JumpList::CreateIconFiles(const base::FilePath& icon_dir,
624 const ShellLinkItemList& item_list,
625 size_t max_items,
626 URLIconCache* icon_cache) {
627 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407.
628 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.CreateIconFilesDuration");
629
630 int icons_created = 0;
631
632 // Reuse icons for urls that already present in the current JumpList.
633 URLIconCache updated_map;
634 for (ShellLinkItemList::const_iterator iter = item_list.begin();
635 iter != item_list.end() && max_items > 0; ++iter, --max_items) {
636 ShellLinkItem* item = iter->get();
637 auto cache_iter = icon_cache->find(item->url());
638 if (cache_iter != icon_cache->end()) {
639 item->set_icon(cache_iter->second.value(), 0);
640 updated_map[item->url()] = cache_iter->second;
641 } else {
642 base::FilePath icon_path;
643 if (CreateIconFile(item->icon_image(), icon_dir, &icon_path)) {
644 ++icons_created;
645 item->set_icon(icon_path.value(), 0);
646 updated_map[item->url()] = icon_path;
647 }
648 }
649 }
650 icon_cache->swap(updated_map);
651
652 return icons_created;
653 }
654
655 // static
656 int JumpList::UpdateIconFiles(const base::FilePath& icon_dir,
657 const ShellLinkItemList& page_list,
658 size_t slot_limit,
659 URLIconCache* icon_cache) {
660 int icons_created = 0;
661
662 // Clear the JumpList icon folder at |icon_dir| and the cache when
663 // 1) |icon_cache| is empty. This happens when "Most visited" or "Recently
664 // closed" category updates for the 1st time after Chrome is launched.
665 // 2) The number of icons in |icon_dir| has exceeded the limit.
666 if (icon_cache->empty() || FilesExceedLimitInDir(icon_dir, slot_limit * 2)) {
667 DeleteDirectoryContentAndLogRuntime(icon_dir, kFileDeleteLimit);
668 icon_cache->clear();
669 // Create new icons only when the directory exists and is empty.
670 if (base::CreateDirectory(icon_dir) && base::IsDirectoryEmpty(icon_dir))
671 icons_created +=
672 CreateIconFiles(icon_dir, page_list, slot_limit, icon_cache);
673 } else if (base::CreateDirectory(icon_dir)) {
674 icons_created +=
675 CreateIconFiles(icon_dir, page_list, slot_limit, icon_cache);
676 DeleteIconFiles(icon_dir, icon_cache);
677 }
678
679 return icons_created;
680 }
681
682 // static
683 void JumpList::RunUpdateJumpList( 652 void JumpList::RunUpdateJumpList(
684 const base::string16& app_id, 653 const base::string16& app_id,
685 const base::FilePath& profile_dir, 654 const base::FilePath& profile_dir,
686 const ShellLinkItemList& most_visited_pages, 655 const ShellLinkItemList& most_visited_pages,
687 const ShellLinkItemList& recently_closed_pages, 656 const ShellLinkItemList& recently_closed_pages,
688 bool most_visited_should_update, 657 bool most_visited_should_update,
689 bool recently_closed_should_update, 658 bool recently_closed_should_update,
690 IncognitoModePrefs::Availability incognito_availability, 659 IncognitoModePrefs::Availability incognito_availability,
691 UpdateResults* update_results) { 660 UpdateResults* update_results) {
692 if (!JumpListUpdater::IsEnabled()) 661 if (!JumpListUpdater::IsEnabled())
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
775 base::ElapsedTimer commit_update_timer; 744 base::ElapsedTimer commit_update_timer;
776 745
777 // Commit this transaction and send the updated JumpList to Windows. 746 // Commit this transaction and send the updated JumpList to Windows.
778 if (jumplist_updater.CommitUpdate()) 747 if (jumplist_updater.CommitUpdate())
779 update_results->update_success = true; 748 update_results->update_success = true;
780 749
781 if (commit_update_timer.Elapsed() >= kTimeOutForJumplistCommitUpdate) 750 if (commit_update_timer.Elapsed() >= kTimeOutForJumplistCommitUpdate)
782 update_results->update_timeout = true; 751 update_results->update_timeout = true;
783 } 752 }
784 753
785 void JumpList::OnRunUpdateCompletion( 754 // static
786 std::unique_ptr<UpdateResults> update_results) { 755 int JumpList::UpdateIconFiles(const base::FilePath& icon_dir,
787 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 756 const ShellLinkItemList& page_list,
757 size_t slot_limit,
758 URLIconCache* icon_cache) {
759 int icons_created = 0;
788 760
789 // Update JumpList member variables based on the results from the update run 761 // Clear the JumpList icon folder at |icon_dir| and the cache when
790 // just finished. 762 // 1) |icon_cache| is empty. This happens when "Most visited" or "Recently
791 if (update_results->update_timeout) 763 // closed" category updates for the 1st time after Chrome is launched.
792 updates_to_skip_ = kUpdatesToSkipUnderHeavyLoad; 764 // 2) The number of icons in |icon_dir| has exceeded the limit.
793 765 if (icon_cache->empty() || FilesExceedLimitInDir(icon_dir, slot_limit * 2)) {
794 if (update_results->update_success) { 766 DeleteDirectoryContentAndLogRuntime(icon_dir, kFileDeleteLimit);
795 most_visited_icons_.swap(update_results->most_visited_icons_in_update); 767 icon_cache->clear();
796 recently_closed_icons_.swap( 768 // Create new icons only when the directory exists and is empty.
797 update_results->recently_closed_icons_in_update); 769 if (base::CreateDirectory(icon_dir) && base::IsDirectoryEmpty(icon_dir))
798 most_visited_should_update_ = false; 770 icons_created +=
799 recently_closed_should_update_ = false; 771 CreateIconFiles(icon_dir, page_list, slot_limit, icon_cache);
772 } else if (base::CreateDirectory(icon_dir)) {
773 icons_created +=
774 CreateIconFiles(icon_dir, page_list, slot_limit, icon_cache);
775 DeleteIconFiles(icon_dir, icon_cache);
800 } 776 }
801 777
802 update_in_progress_ = false; 778 return icons_created;
779 }
803 780
804 // If there is any new notification during the update run just finished, start 781 // static
805 // another JumpList update. 782 int JumpList::CreateIconFiles(const base::FilePath& icon_dir,
806 // Otherwise, post tasks to delete the JumpListIcons and JumpListIconsOld 783 const ShellLinkItemList& item_list,
807 // folders as they are no longer needed. Now we have the 784 size_t max_items,
808 // JumpListIcons{MostVisited, RecentClosed} folders instead. 785 URLIconCache* icon_cache) {
809 if (top_sites_has_pending_notification_ || 786 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407.
810 tab_restore_has_pending_notification_) { 787 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.CreateIconFilesDuration");
811 InitializeTimerForUpdate();
812 } else {
813 base::FilePath profile_dir = profile_->GetPath();
814 base::FilePath icon_dir =
815 GenerateJumplistIconDirName(profile_dir, FILE_PATH_LITERAL(""));
816 delete_jumplisticons_task_runner_->PostTask(
817 FROM_HERE,
818 base::Bind(&DeleteDirectory, std::move(icon_dir), kFileDeleteLimit));
819 788
820 base::FilePath icon_dir_old = 789 int icons_created = 0;
821 GenerateJumplistIconDirName(profile_dir, FILE_PATH_LITERAL("Old")); 790
822 delete_jumplisticons_task_runner_->PostTask( 791 // Reuse icons for urls that already present in the current JumpList.
823 FROM_HERE, base::Bind(&DeleteDirectory, std::move(icon_dir_old), 792 URLIconCache updated_map;
824 kFileDeleteLimit)); 793 for (ShellLinkItemList::const_iterator iter = item_list.begin();
794 iter != item_list.end() && max_items > 0; ++iter, --max_items) {
795 ShellLinkItem* item = iter->get();
796 auto cache_iter = icon_cache->find(item->url());
797 if (cache_iter != icon_cache->end()) {
798 item->set_icon(cache_iter->second.value(), 0);
799 updated_map[item->url()] = cache_iter->second;
800 } else {
801 base::FilePath icon_path;
802 if (CreateIconFile(item->icon_image(), icon_dir, &icon_path)) {
803 ++icons_created;
804 item->set_icon(icon_path.value(), 0);
805 updated_map[item->url()] = icon_path;
806 }
807 }
825 } 808 }
809 icon_cache->swap(updated_map);
810
811 return icons_created;
826 } 812 }
813
814 // static
815 void JumpList::DeleteIconFiles(const base::FilePath& icon_dir,
816 URLIconCache* icon_cache) {
817 // Put all cached icon file paths into a set.
818 base::flat_set<base::FilePath> cached_files;
819 cached_files.reserve(icon_cache->size());
820
821 for (const auto& url_path_pair : *icon_cache)
822 cached_files.insert(url_path_pair.second);
823
824 DeleteNonCachedFiles(icon_dir, cached_files);
825 }
OLDNEW
« chrome/browser/win/jumplist.h ('K') | « chrome/browser/win/jumplist.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698