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 |