Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/win/jumplist.h" | 5 #include "chrome/browser/win/jumplist.h" |
| 6 | 6 |
| 7 #include "base/base_paths.h" | 7 #include "base/base_paths.h" |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/bind_helpers.h" | 9 #include "base/bind_helpers.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |