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

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: 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
« 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 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 // static 253 void JumpList::TopSitesLoaded(history::TopSites* top_sites) {}
254 bool JumpList::Enabled() { 254
255 return JumpListUpdater::IsEnabled(); 255 void JumpList::TopSitesChanged(history::TopSites* top_sites,
256 ChangeReason change_reason) {
257 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
258
259 top_sites_has_pending_notification_ = true;
260
261 // Postpone handling this notification until a pending update completes.
262 if (update_in_progress_)
263 return;
264
265 // If we have a pending favicon request, cancel it here as it's out of date.
266 CancelPendingUpdate();
267
268 // Initialize the one-shot timer to update the JumpList in a while.
269 InitializeTimerForUpdate();
256 } 270 }
257 271
258 void JumpList::CancelPendingUpdate() { 272 void JumpList::TabRestoreServiceChanged(sessions::TabRestoreService* service) {
259 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 273 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
260 274
261 // Cancel a pending most-visited URL fetch by invalidating the weak pointer. 275 tab_restore_has_pending_notification_ = true;
262 weak_ptr_factory_.InvalidateWeakPtrs();
263 276
264 // Cancel a pending favicon loading by invalidating its task id. 277 // Postpone handling this notification until a pending update completes.
265 if (task_id_ != base::CancelableTaskTracker::kBadTaskId) { 278 if (update_in_progress_)
266 cancelable_task_tracker_.TryCancel(task_id_); 279 return;
267 task_id_ = base::CancelableTaskTracker::kBadTaskId; 280
281 // if we have a pending favicon request, cancel it here as it's out of date.
282 CancelPendingUpdate();
283
284 // Initialize the one-shot timer to update the JumpList in a while.
285 InitializeTimerForUpdate();
286 }
287
288 void JumpList::TabRestoreServiceDestroyed(
289 sessions::TabRestoreService* service) {}
290
291 void JumpList::InitializeTimerForUpdate() {
292 if (timer_.IsRunning()) {
293 timer_.Reset();
294 } else {
295 // base::Unretained is safe since |this| is guaranteed to outlive timer_.
296 timer_.Start(FROM_HERE, kDelayForJumplistUpdate,
297 base::Bind(&JumpList::OnDelayTimer, base::Unretained(this)));
268 } 298 }
269 } 299 }
270 300
271 void JumpList::Terminate() { 301 void JumpList::OnDelayTimer() {
272 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 302 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
273 timer_.Stop(); 303
274 CancelPendingUpdate(); 304 if (updates_to_skip_ > 0) {
275 update_in_progress_ = false; 305 --updates_to_skip_;
276 if (profile_) { 306 return;
277 sessions::TabRestoreService* tab_restore_service = 307 }
278 TabRestoreServiceFactory::GetForProfile(profile_); 308
279 if (tab_restore_service) 309 // Retrieve the recently closed URLs synchronously.
280 tab_restore_service->RemoveObserver(this); 310 if (tab_restore_has_pending_notification_) {
311 tab_restore_has_pending_notification_ = false;
312 ProcessTabRestoreServiceNotification();
313 }
314
315 // If TopSites has updates, retrieve the URLs asynchronously, and on its
316 // completion, trigger favicon loading.
317 // Otherwise, call StartLoadingFavicon directly to start favicon loading.
318 if (top_sites_has_pending_notification_)
319 ProcessTopSitesNotification();
320 else
321 StartLoadingFavicon();
322 }
323
324 void JumpList::ProcessTopSitesNotification() {
325 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
326
327 // Opening the first tab in one session triggers a TopSite history sync.
328 // Delay this sync till the first tab is closed to allow the "recently closed"
329 // category from last session to stay longer. All previous pending
330 // notifications from TopSites are ignored.
331 if (!has_tab_closed_) {
332 top_sites_has_pending_notification_ = false;
333 return;
334 }
335
336 scoped_refptr<history::TopSites> top_sites =
337 TopSitesFactory::GetForProfile(profile_);
338 if (top_sites) {
339 top_sites->GetMostVisitedURLs(
340 base::Bind(&JumpList::OnMostVisitedURLsAvailable,
341 weak_ptr_factory_.GetWeakPtr()),
342 false);
343 }
344 }
345
346 void JumpList::ProcessTabRestoreServiceNotification() {
347 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
348
349 // Create a list of ShellLinkItems from the "Recently Closed" pages.
350 // As noted above, we create a ShellLinkItem objects with the following
351 // parameters.
352 // * arguments
353 // The last URL of the tab object.
354 // * title
355 // The title of the last URL.
356 // * icon
357 // An empty string. This value is to be updated in OnFaviconDataAvailable().
358
359 sessions::TabRestoreService* tab_restore_service =
360 TabRestoreServiceFactory::GetForProfile(profile_);
361
362 recently_closed_pages_.clear();
363
364 for (const auto& entry : tab_restore_service->entries()) {
365 if (recently_closed_pages_.size() >= kRecentlyClosedItems)
366 break;
367 switch (entry->type) {
368 case sessions::TabRestoreService::TAB:
369 AddTab(static_cast<const sessions::TabRestoreService::Tab&>(*entry),
370 kRecentlyClosedItems);
371 break;
372 case sessions::TabRestoreService::WINDOW:
373 AddWindow(
374 static_cast<const sessions::TabRestoreService::Window&>(*entry),
375 kRecentlyClosedItems);
376 break;
377 }
378 }
379
380 recently_closed_should_update_ = true;
381
382 // Force a TopSite history sync when closing a first tab in one session.
383 if (!has_tab_closed_) {
384 has_tab_closed_ = true;
281 scoped_refptr<history::TopSites> top_sites = 385 scoped_refptr<history::TopSites> top_sites =
282 TopSitesFactory::GetForProfile(profile_); 386 TopSitesFactory::GetForProfile(profile_);
283 if (top_sites) 387 if (top_sites)
284 top_sites->RemoveObserver(this); 388 top_sites->SyncWithHistory();
285 pref_change_registrar_.reset();
286 } 389 }
287 profile_ = nullptr;
288 }
289
290 void JumpList::Shutdown() {
291 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
292 Terminate();
293 } 390 }
294 391
295 void JumpList::OnMostVisitedURLsAvailable( 392 void JumpList::OnMostVisitedURLsAvailable(
296 const history::MostVisitedURLList& urls) { 393 const history::MostVisitedURLList& urls) {
297 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 394 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
298 395
299 top_sites_has_pending_notification_ = false; 396 top_sites_has_pending_notification_ = false;
300 397
301 // There is no need to update the JumpList if the top most visited sites in 398 // There is no need to update the JumpList if the top most visited sites in
302 // display have not changed. 399 // display have not changed.
(...skipping 16 matching lines...) Expand all
319 most_visited_pages_.push_back(link); 416 most_visited_pages_.push_back(link);
320 icon_urls_.emplace_back(std::move(url_string), std::move(link)); 417 icon_urls_.emplace_back(std::move(url_string), std::move(link));
321 } 418 }
322 419
323 most_visited_should_update_ = true; 420 most_visited_should_update_ = true;
324 421
325 // Send a query that retrieves the first favicon. 422 // Send a query that retrieves the first favicon.
326 StartLoadingFavicon(); 423 StartLoadingFavicon();
327 } 424 }
328 425
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, 426 bool JumpList::AddTab(const sessions::TabRestoreService::Tab& tab,
349 size_t max_items) { 427 size_t max_items) {
350 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 428 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
351 429
352 // This code adds the URL and the title strings of the given tab to the 430 // This code adds the URL and the title strings of the given tab to the
353 // JumpList variables. 431 // JumpList variables.
354 if (recently_closed_pages_.size() >= max_items) 432 if (recently_closed_pages_.size() >= max_items)
355 return false; 433 return false;
356 434
357 scoped_refptr<ShellLinkItem> link = CreateShellLink(); 435 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, 556 local_most_visited_pages, local_recently_closed_pages,
479 most_visited_should_update, recently_closed_should_update, 557 most_visited_should_update, recently_closed_should_update,
480 incognito_availability, update_results.get()), 558 incognito_availability, update_results.get()),
481 base::Bind(&JumpList::OnRunUpdateCompletion, 559 base::Bind(&JumpList::OnRunUpdateCompletion,
482 weak_ptr_factory_.GetWeakPtr(), 560 weak_ptr_factory_.GetWeakPtr(),
483 base::Passed(std::move(update_results))))) { 561 base::Passed(std::move(update_results))))) {
484 OnRunUpdateCompletion(base::MakeUnique<UpdateResults>()); 562 OnRunUpdateCompletion(base::MakeUnique<UpdateResults>());
485 } 563 }
486 } 564 }
487 565
488 void JumpList::TopSitesLoaded(history::TopSites* top_sites) { 566 void JumpList::OnRunUpdateCompletion(
489 } 567 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_); 568 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
494 569
495 top_sites_has_pending_notification_ = true; 570 // Update JumpList member variables based on the results from the update run
571 // just finished.
572 if (update_results->update_timeout)
573 updates_to_skip_ = kUpdatesToSkipUnderHeavyLoad;
496 574
497 // Postpone handling this notification until a pending update completes. 575 if (update_results->update_success) {
498 if (update_in_progress_) 576 most_visited_icons_.swap(update_results->most_visited_icons_in_update);
499 return; 577 recently_closed_icons_.swap(
578 update_results->recently_closed_icons_in_update);
579 most_visited_should_update_ = false;
580 recently_closed_should_update_ = false;
581 }
500 582
501 // If we have a pending favicon request, cancel it here as it's out of date. 583 update_in_progress_ = false;
502 CancelPendingUpdate();
503 584
504 // Initialize the one-shot timer to update the JumpList in a while. 585 // If there is any new notification during the update run just finished, start
505 InitializeTimerForUpdate(); 586 // another JumpList update.
506 } 587 // Otherwise, post tasks to delete the JumpListIcons and JumpListIconsOld
588 // folders as they are no longer needed. Now we have the
589 // JumpListIcons{MostVisited, RecentClosed} folders instead.
590 if (top_sites_has_pending_notification_ ||
591 tab_restore_has_pending_notification_) {
592 InitializeTimerForUpdate();
593 } else {
594 base::FilePath profile_dir = profile_->GetPath();
595 base::FilePath icon_dir =
596 GenerateJumplistIconDirName(profile_dir, FILE_PATH_LITERAL(""));
597 delete_jumplisticons_task_runner_->PostTask(
598 FROM_HERE,
599 base::Bind(&DeleteDirectory, std::move(icon_dir), kFileDeleteLimit));
507 600
508 void JumpList::InitializeTimerForUpdate() { 601 base::FilePath icon_dir_old =
509 if (timer_.IsRunning()) { 602 GenerateJumplistIconDirName(profile_dir, FILE_PATH_LITERAL("Old"));
510 timer_.Reset(); 603 delete_jumplisticons_task_runner_->PostTask(
511 } else { 604 FROM_HERE, base::Bind(&DeleteDirectory, std::move(icon_dir_old),
512 // base::Unretained is safe since |this| is guaranteed to outlive timer_. 605 kFileDeleteLimit));
513 timer_.Start(FROM_HERE, kDelayForJumplistUpdate,
514 base::Bind(&JumpList::OnDelayTimer, base::Unretained(this)));
515 } 606 }
516 } 607 }
517 608
518 void JumpList::OnDelayTimer() { 609 void JumpList::CancelPendingUpdate() {
519 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 610 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
520 611
521 if (updates_to_skip_ > 0) { 612 // Cancel a pending most-visited URL fetch by invalidating the weak pointer.
522 --updates_to_skip_; 613 weak_ptr_factory_.InvalidateWeakPtrs();
523 return;
524 }
525 614
526 // Retrieve the recently closed URLs synchronously. 615 // Cancel a pending favicon loading by invalidating its task id.
527 if (tab_restore_has_pending_notification_) { 616 if (task_id_ != base::CancelableTaskTracker::kBadTaskId) {
528 tab_restore_has_pending_notification_ = false; 617 cancelable_task_tracker_.TryCancel(task_id_);
529 ProcessTabRestoreServiceNotification(); 618 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 } 619 }
561 } 620 }
562 621
563 void JumpList::ProcessTabRestoreServiceNotification() { 622 void JumpList::Terminate() {
564 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 623 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
565 624 timer_.Stop();
566 // Create a list of ShellLinkItems from the "Recently Closed" pages. 625 CancelPendingUpdate();
567 // As noted above, we create a ShellLinkItem objects with the following 626 update_in_progress_ = false;
568 // parameters. 627 if (profile_) {
569 // * arguments 628 sessions::TabRestoreService* tab_restore_service =
570 // The last URL of the tab object. 629 TabRestoreServiceFactory::GetForProfile(profile_);
571 // * title 630 if (tab_restore_service)
572 // The title of the last URL. 631 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 = 632 scoped_refptr<history::TopSites> top_sites =
603 TopSitesFactory::GetForProfile(profile_); 633 TopSitesFactory::GetForProfile(profile_);
604 if (top_sites) 634 if (top_sites)
605 top_sites->SyncWithHistory(); 635 top_sites->RemoveObserver(this);
636 pref_change_registrar_.reset();
606 } 637 }
638 profile_ = nullptr;
639 }
640
641 void JumpList::Shutdown() {
grt (UTC plus 2) 2017/06/14 10:54:12 please put all methods here in the same order as t
chengx 2017/06/14 16:53:23 Done.
642 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
643 Terminate();
607 } 644 }
608 645
609 // static 646 // static
610 void JumpList::DeleteIconFiles(const base::FilePath& icon_dir, 647 bool JumpList::Enabled() {
611 URLIconCache* icon_cache) { 648 return JumpListUpdater::IsEnabled();
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 } 649 }
621 650
622 // static 651 // 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
« 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