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 <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
12 #include "base/files/file_util.h" | 12 #include "base/files/file_util.h" |
13 #include "base/macros.h" | 13 #include "base/macros.h" |
14 #include "base/metrics/histogram_macros.h" | 14 #include "base/metrics/histogram_macros.h" |
15 #include "base/path_service.h" | 15 #include "base/path_service.h" |
16 #include "base/sequenced_task_runner.h" | 16 #include "base/sequenced_task_runner.h" |
17 #include "base/single_thread_task_runner.h" | 17 #include "base/single_thread_task_runner.h" |
18 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
19 #include "base/strings/utf_string_conversions.h" | 19 #include "base/strings/utf_string_conversions.h" |
20 #include "base/task_scheduler/post_task.h" | 20 #include "base/task_scheduler/post_task.h" |
21 #include "base/threading/thread.h" | 21 #include "base/threading/thread.h" |
22 #include "base/threading/thread_restrictions.h" | 22 #include "base/threading/thread_restrictions.h" |
23 #include "base/timer/elapsed_timer.h" | |
23 #include "base/trace_event/trace_event.h" | 24 #include "base/trace_event/trace_event.h" |
24 #include "chrome/browser/chrome_notification_types.h" | 25 #include "chrome/browser/chrome_notification_types.h" |
25 #include "chrome/browser/favicon/favicon_service_factory.h" | 26 #include "chrome/browser/favicon/favicon_service_factory.h" |
26 #include "chrome/browser/history/top_sites_factory.h" | 27 #include "chrome/browser/history/top_sites_factory.h" |
27 #include "chrome/browser/metrics/jumplist_metrics_win.h" | 28 #include "chrome/browser/metrics/jumplist_metrics_win.h" |
28 #include "chrome/browser/profiles/profile.h" | 29 #include "chrome/browser/profiles/profile.h" |
29 #include "chrome/browser/sessions/tab_restore_service_factory.h" | 30 #include "chrome/browser/sessions/tab_restore_service_factory.h" |
30 #include "chrome/browser/shell_integration_win.h" | 31 #include "chrome/browser/shell_integration_win.h" |
31 #include "chrome/browser/win/jumplist_file_util.h" | 32 #include "chrome/browser/win/jumplist_file_util.h" |
32 #include "chrome/common/chrome_constants.h" | 33 #include "chrome/common/chrome_constants.h" |
(...skipping 24 matching lines...) Expand all Loading... | |
57 #include "ui/gfx/image/image_skia.h" | 58 #include "ui/gfx/image/image_skia.h" |
58 #include "ui/gfx/image/image_skia_rep.h" | 59 #include "ui/gfx/image/image_skia_rep.h" |
59 #include "url/gurl.h" | 60 #include "url/gurl.h" |
60 | 61 |
61 using content::BrowserThread; | 62 using content::BrowserThread; |
62 using JumpListData = JumpList::JumpListData; | 63 using JumpListData = JumpList::JumpListData; |
63 | 64 |
64 namespace { | 65 namespace { |
65 | 66 |
66 // Delay jumplist updates to allow collapsing of redundant update requests. | 67 // Delay jumplist updates to allow collapsing of redundant update requests. |
67 const int kDelayForJumplistUpdateInMS = 3500; | 68 constexpr base::TimeDelta kDelayForJumplistUpdateInMS = |
69 base::TimeDelta::FromMilliseconds(3500); | |
70 | |
71 // Timeout jumplist updates for users with extremely slow OS. | |
72 constexpr base::TimeDelta kTimeOutForJumplistUpdateInMS = | |
73 base::TimeDelta::FromMilliseconds(500); | |
68 | 74 |
69 // Append the common switches to each shell link. | 75 // Append the common switches to each shell link. |
70 void AppendCommonSwitches(ShellLinkItem* shell_link) { | 76 void AppendCommonSwitches(ShellLinkItem* shell_link) { |
71 const char* kSwitchNames[] = { switches::kUserDataDir }; | 77 const char* kSwitchNames[] = { switches::kUserDataDir }; |
72 const base::CommandLine& command_line = | 78 const base::CommandLine& command_line = |
73 *base::CommandLine::ForCurrentProcess(); | 79 *base::CommandLine::ForCurrentProcess(); |
74 shell_link->GetCommandLine()->CopySwitchesFrom(command_line, | 80 shell_link->GetCommandLine()->CopySwitchesFrom(command_line, |
75 kSwitchNames, | 81 kSwitchNames, |
76 arraysize(kSwitchNames)); | 82 arraysize(kSwitchNames)); |
77 } | 83 } |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
181 const base::FilePath& icon_dir, | 187 const base::FilePath& icon_dir, |
182 const ShellLinkItemList& most_visited_pages, | 188 const ShellLinkItemList& most_visited_pages, |
183 const ShellLinkItemList& recently_closed_pages, | 189 const ShellLinkItemList& recently_closed_pages, |
184 IncognitoModePrefs::Availability incognito_availability) { | 190 IncognitoModePrefs::Availability incognito_availability) { |
185 // JumpList is implemented only on Windows 7 or later. | 191 // JumpList is implemented only on Windows 7 or later. |
186 // So, we should return now when this function is called on earlier versions | 192 // So, we should return now when this function is called on earlier versions |
187 // of Windows. | 193 // of Windows. |
188 if (!JumpListUpdater::IsEnabled()) | 194 if (!JumpListUpdater::IsEnabled()) |
189 return true; | 195 return true; |
190 | 196 |
197 // Records the time cost of starting a JumpListUpdater. | |
198 base::ElapsedTimer begin_update_timer; | |
199 | |
191 JumpListUpdater jumplist_updater(app_id); | 200 JumpListUpdater jumplist_updater(app_id); |
192 if (!jumplist_updater.BeginUpdate()) | 201 if (!jumplist_updater.BeginUpdate()) |
193 return false; | 202 return false; |
194 | 203 |
204 // Stops jumplist update if JumpListUpdater's start times out, as it's very | |
205 // likely the following update steps will also take a long time. | |
206 if (begin_update_timer.Elapsed() >= kTimeOutForJumplistUpdateInMS) | |
207 return false; | |
208 | |
195 // We allocate 60% of the given JumpList slots to "most-visited" items | 209 // We allocate 60% of the given JumpList slots to "most-visited" items |
196 // and 40% to "recently-closed" items, respectively. | 210 // and 40% to "recently-closed" items, respectively. |
197 // Nevertheless, if there are not so many items in |recently_closed_pages|, | 211 // Nevertheless, if there are not so many items in |recently_closed_pages|, |
198 // we give the remaining slots to "most-visited" items. | 212 // we give the remaining slots to "most-visited" items. |
199 // The default maximum number of items to display in JumpList is 10. | 213 // The default maximum number of items to display in JumpList is 10. |
200 // https://msdn.microsoft.com/en-us/library/windows/desktop/dd378398(v=vs.85). aspx | 214 // https://msdn.microsoft.com/en-us/library/windows/desktop/dd378398(v=vs.85). aspx |
201 const int kMostVisited = 60; | 215 const int kMostVisited = 60; |
202 const int kRecentlyClosed = 40; | 216 const int kRecentlyClosed = 40; |
203 const int kTotal = kMostVisited + kRecentlyClosed; | 217 const int kTotal = kMostVisited + kRecentlyClosed; |
204 size_t most_visited_items = | 218 size_t most_visited_items = |
205 MulDiv(jumplist_updater.user_max_items(), kMostVisited, kTotal); | 219 MulDiv(jumplist_updater.user_max_items(), kMostVisited, kTotal); |
206 size_t recently_closed_items = | 220 size_t recently_closed_items = |
207 jumplist_updater.user_max_items() - most_visited_items; | 221 jumplist_updater.user_max_items() - most_visited_items; |
208 if (recently_closed_pages.size() < recently_closed_items) { | 222 if (recently_closed_pages.size() < recently_closed_items) { |
209 most_visited_items += recently_closed_items - recently_closed_pages.size(); | 223 most_visited_items += recently_closed_items - recently_closed_pages.size(); |
210 recently_closed_items = recently_closed_pages.size(); | 224 recently_closed_items = recently_closed_pages.size(); |
211 } | 225 } |
212 | 226 |
213 // Delete the content in JumpListIcons folder and log the results to UMA. | 227 // Delete the content in JumpListIcons folder and log the results to UMA. |
214 DeleteDirectoryContentAndLogResults(icon_dir, kFileDeleteLimit); | 228 DeleteDirectoryContentAndLogResults(icon_dir, kFileDeleteLimit); |
215 | 229 |
216 // If JumpListIcons directory doesn't exist (we have tried to create it | 230 // If JumpListIcons directory doesn't exist (we have tried to create it |
217 // already) or is not empty, skip updating the jumplist icons. The jumplist | 231 // already) or is not empty, skip updating the jumplist icons. The jumplist |
218 // links should be updated anyway, as it doesn't involve disk IO. In this | 232 // links should be updated anyway, as it doesn't involve disk IO. In this |
219 // case, Chrome's icon will be used for the new links. | 233 // case, Chrome's icon will be used for the new links. |
220 | 234 |
221 if (base::DirectoryExists(icon_dir) && base::IsDirectoryEmpty(icon_dir)) { | 235 bool is_dir_existed_and_empty = |
222 // TODO(chengx): Remove this UMA metric after fixing http://crbug.com/40407. | 236 base::DirectoryExists(icon_dir) && base::IsDirectoryEmpty(icon_dir); |
223 UMA_HISTOGRAM_COUNTS_100( | |
224 "WinJumplist.CreateIconFilesCount", | |
225 most_visited_pages.size() + recently_closed_pages.size()); | |
Ilya Sherman
2017/04/20 21:24:24
Should this metric be marked as obsolete as well?
chengx
2017/04/20 21:49:04
Yes, it's obsolete. Now it's fixed in histograms.x
| |
226 | 237 |
227 // Create icon files for shortcuts in the "Most Visited" category. | 238 // Create icon files for shortcuts in the "Most Visited" category. |
239 if (is_dir_existed_and_empty) | |
228 CreateIconFiles(icon_dir, most_visited_pages, most_visited_items); | 240 CreateIconFiles(icon_dir, most_visited_pages, most_visited_items); |
229 | 241 |
230 // Create icon files for shortcuts in the "Recently Closed" category. | |
231 CreateIconFiles(icon_dir, recently_closed_pages, recently_closed_items); | |
232 } | |
233 | |
234 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. | |
235 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.UpdateJumpListDuration"); | |
236 | |
237 // Update the "Most Visited" category of the JumpList if it exists. | 242 // Update the "Most Visited" category of the JumpList if it exists. |
238 // This update request is applied into the JumpList when we commit this | 243 // This update request is applied into the JumpList when we commit this |
239 // transaction. | 244 // transaction. |
240 if (!jumplist_updater.AddCustomCategory( | 245 if (!jumplist_updater.AddCustomCategory( |
241 l10n_util::GetStringUTF16(IDS_NEW_TAB_MOST_VISITED), | 246 l10n_util::GetStringUTF16(IDS_NEW_TAB_MOST_VISITED), |
242 most_visited_pages, most_visited_items)) { | 247 most_visited_pages, most_visited_items)) { |
243 return false; | 248 return false; |
244 } | 249 } |
245 | 250 |
251 // Create icon files for shortcuts in the "Recently Closed" category. | |
252 if (is_dir_existed_and_empty) | |
253 CreateIconFiles(icon_dir, recently_closed_pages, recently_closed_items); | |
254 | |
246 // Update the "Recently Closed" category of the JumpList. | 255 // Update the "Recently Closed" category of the JumpList. |
247 if (!jumplist_updater.AddCustomCategory( | 256 if (!jumplist_updater.AddCustomCategory( |
248 l10n_util::GetStringUTF16(IDS_RECENTLY_CLOSED), | 257 l10n_util::GetStringUTF16(IDS_RECENTLY_CLOSED), |
249 recently_closed_pages, recently_closed_items)) { | 258 recently_closed_pages, recently_closed_items)) { |
250 return false; | 259 return false; |
251 } | 260 } |
252 | 261 |
253 // Update the "Tasks" category of the JumpList. | 262 // Update the "Tasks" category of the JumpList. |
254 if (!UpdateTaskCategory(&jumplist_updater, incognito_availability)) | 263 if (!UpdateTaskCategory(&jumplist_updater, incognito_availability)) |
255 return false; | 264 return false; |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
588 DCHECK(CalledOnValidThread()); | 597 DCHECK(CalledOnValidThread()); |
589 | 598 |
590 TRACE_EVENT0("browser", "JumpList::PostRunUpdate"); | 599 TRACE_EVENT0("browser", "JumpList::PostRunUpdate"); |
591 // Initialize the one-shot timer to update the jumplists in a while. | 600 // Initialize the one-shot timer to update the jumplists in a while. |
592 // If there is already a request queued then cancel it and post the new | 601 // If there is already a request queued then cancel it and post the new |
593 // request. This ensures that JumpListUpdates won't happen until there has | 602 // request. This ensures that JumpListUpdates won't happen until there has |
594 // been a brief quiet period, thus avoiding update storms. | 603 // been a brief quiet period, thus avoiding update storms. |
595 if (timer_.IsRunning()) { | 604 if (timer_.IsRunning()) { |
596 timer_.Reset(); | 605 timer_.Reset(); |
597 } else { | 606 } else { |
598 timer_.Start(FROM_HERE, | 607 timer_.Start(FROM_HERE, kDelayForJumplistUpdateInMS, this, |
599 base::TimeDelta::FromMilliseconds(kDelayForJumplistUpdateInMS), | |
600 this, | |
601 &JumpList::DeferredRunUpdate); | 608 &JumpList::DeferredRunUpdate); |
602 } | 609 } |
603 } | 610 } |
604 | 611 |
605 void JumpList::DeferredRunUpdate() { | 612 void JumpList::DeferredRunUpdate() { |
606 DCHECK(CalledOnValidThread()); | 613 DCHECK(CalledOnValidThread()); |
607 | 614 |
608 TRACE_EVENT0("browser", "JumpList::DeferredRunUpdate"); | 615 TRACE_EVENT0("browser", "JumpList::DeferredRunUpdate"); |
609 // Check if incognito windows (or normal windows) are disabled by policy. | 616 // Check if incognito windows (or normal windows) are disabled by policy. |
610 IncognitoModePrefs::Availability incognito_availability = | 617 IncognitoModePrefs::Availability incognito_availability = |
(...skipping 18 matching lines...) Expand all Loading... | |
629 void JumpList::TopSitesLoaded(history::TopSites* top_sites) { | 636 void JumpList::TopSitesLoaded(history::TopSites* top_sites) { |
630 } | 637 } |
631 | 638 |
632 void JumpList::TopSitesChanged(history::TopSites* top_sites, | 639 void JumpList::TopSitesChanged(history::TopSites* top_sites, |
633 ChangeReason change_reason) { | 640 ChangeReason change_reason) { |
634 top_sites->GetMostVisitedURLs( | 641 top_sites->GetMostVisitedURLs( |
635 base::Bind(&JumpList::OnMostVisitedURLsAvailable, | 642 base::Bind(&JumpList::OnMostVisitedURLsAvailable, |
636 weak_ptr_factory_.GetWeakPtr()), | 643 weak_ptr_factory_.GetWeakPtr()), |
637 false); | 644 false); |
638 } | 645 } |
OLD | NEW |