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

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