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

Side by Side Diff: chrome/browser/win/jumplist.cc

Issue 2732313002: Move JumplistIcon to JumplistIconOld only via renaming, not copy-n-delete (Closed)
Patch Set: Add a new metric in histograms.xml Created 3 years, 9 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
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 <Shlwapi.h>
8 #include <windows.h>
9
7 #include "base/bind.h" 10 #include "base/bind.h"
8 #include "base/bind_helpers.h" 11 #include "base/bind_helpers.h"
9 #include "base/callback_helpers.h" 12 #include "base/callback_helpers.h"
10 #include "base/command_line.h" 13 #include "base/command_line.h"
11 #include "base/files/file_util.h" 14 #include "base/files/file_util.h"
12 #include "base/macros.h" 15 #include "base/macros.h"
13 #include "base/metrics/histogram_macros.h" 16 #include "base/metrics/histogram_macros.h"
14 #include "base/path_service.h" 17 #include "base/path_service.h"
15 #include "base/strings/string_util.h" 18 #include "base/strings/string_util.h"
16 #include "base/strings/utf_string_conversions.h" 19 #include "base/strings/utf_string_conversions.h"
17 #include "base/threading/thread.h" 20 #include "base/threading/thread.h"
21 #include "base/threading/thread_restrictions.h"
18 #include "base/trace_event/trace_event.h" 22 #include "base/trace_event/trace_event.h"
19 #include "chrome/browser/chrome_notification_types.h" 23 #include "chrome/browser/chrome_notification_types.h"
20 #include "chrome/browser/favicon/favicon_service_factory.h" 24 #include "chrome/browser/favicon/favicon_service_factory.h"
21 #include "chrome/browser/history/top_sites_factory.h" 25 #include "chrome/browser/history/top_sites_factory.h"
22 #include "chrome/browser/metrics/jumplist_metrics_win.h" 26 #include "chrome/browser/metrics/jumplist_metrics_win.h"
23 #include "chrome/browser/profiles/profile.h" 27 #include "chrome/browser/profiles/profile.h"
24 #include "chrome/browser/sessions/tab_restore_service_factory.h" 28 #include "chrome/browser/sessions/tab_restore_service_factory.h"
25 #include "chrome/browser/shell_integration_win.h" 29 #include "chrome/browser/shell_integration_win.h"
26 #include "chrome/common/chrome_constants.h" 30 #include "chrome/common/chrome_constants.h"
27 #include "chrome/common/chrome_switches.h" 31 #include "chrome/common/chrome_switches.h"
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 if (!UpdateTaskCategory(&jumplist_updater, incognito_availability)) 222 if (!UpdateTaskCategory(&jumplist_updater, incognito_availability))
219 return false; 223 return false;
220 224
221 // Commit this transaction and send the updated JumpList to Windows. 225 // Commit this transaction and send the updated JumpList to Windows.
222 if (!jumplist_updater.CommitUpdate()) 226 if (!jumplist_updater.CommitUpdate())
223 return false; 227 return false;
224 228
225 return true; 229 return true;
226 } 230 }
227 231
232 // Renames the directory |from_dir| to |to_path|. This method fails if any
233 // process has a handle open in |from_dir| or if |to_path| exists. Base::Move()
234 // tries to rename a file and if this fails, it tries copy-n-delete; This
235 // RenameDirectory method only does the rename part.
236 bool RenameDirectory(const base::FilePath& from_path,
237 const base::FilePath& to_path) {
238 base::ThreadRestrictions::AssertIOAllowed();
239 if (from_path.ReferencesParent() || to_path.ReferencesParent())
240 return false;
241 if (from_path.value().length() >= MAX_PATH ||
242 to_path.value().length() >= MAX_PATH) {
243 return false;
244 }
245 return MoveFileEx(from_path.value().c_str(), to_path.value().c_str(), 0) != 0;
246 }
247
228 // Updates the jumplist, once all the data has been fetched. 248 // Updates the jumplist, once all the data has been fetched.
229 void RunUpdateOnFileThread( 249 void RunUpdateOnFileThread(
230 IncognitoModePrefs::Availability incognito_availability, 250 IncognitoModePrefs::Availability incognito_availability,
231 const std::wstring& app_id, 251 const std::wstring& app_id,
232 const base::FilePath& icon_dir, 252 const base::FilePath& icon_dir,
233 base::RefCountedData<JumpListData>* ref_counted_data) { 253 base::RefCountedData<JumpListData>* ref_counted_data) {
234 JumpListData* data = &ref_counted_data->data; 254 JumpListData* data = &ref_counted_data->data;
235 ShellLinkItemList local_most_visited_pages; 255 ShellLinkItemList local_most_visited_pages;
236 ShellLinkItemList local_recently_closed_pages; 256 ShellLinkItemList local_recently_closed_pages;
237 257
238 { 258 {
239 base::AutoLock auto_lock(data->list_lock_); 259 base::AutoLock auto_lock(data->list_lock_);
240 // Make sure we are not out of date: if icon_urls_ is not empty, then 260 // Make sure we are not out of date: if icon_urls_ is not empty, then
241 // another notification has been received since we processed this one 261 // another notification has been received since we processed this one
242 if (!data->icon_urls_.empty()) 262 if (!data->icon_urls_.empty())
243 return; 263 return;
244 264
245 // Make local copies of lists so we can release the lock. 265 // Make local copies of lists so we can release the lock.
246 local_most_visited_pages = data->most_visited_pages_; 266 local_most_visited_pages = data->most_visited_pages_;
247 local_recently_closed_pages = data->recently_closed_pages_; 267 local_recently_closed_pages = data->recently_closed_pages_;
248 } 268 }
249 269
250 // Delete the directory which contains old icon files, rename the current 270 // Delete the directory which contains old icon files, rename the current
251 // icon directory, and create a new directory which contains new JumpList 271 // icon directory, and create a new directory which contains new JumpList
252 // icon files. 272 // icon files.
253 base::FilePath icon_dir_old(icon_dir.value() + L"Old"); 273 base::FilePath icon_dir_old = icon_dir.DirName().Append(
274 icon_dir.BaseName().value() + FILE_PATH_LITERAL("Old"));
254 275
255 enum FolderOperationResult { 276 enum FolderOperationResult {
256 SUCCESS = 0, 277 SUCCESS = 0,
257 DELETE_DEST_FAILED = 1 << 0, 278 DELETE_DEST_FAILED = 1 << 0,
258 MOVE_FAILED = 1 << 1, 279 RENAME_FAILED = 1 << 1,
259 DELETE_SRC_FAILED = 1 << 2, 280 DELETE_SRC_CONTENT_FAILED = 1 << 2,
260 CREATE_SRC_FAILED = 1 << 3, 281 DELETE_SRC_DIR_FAILED = 1 << 3,
282 CREATE_SRC_FAILED = 1 << 4,
261 // This value is beyond the sum of all bit fields above and 283 // This value is beyond the sum of all bit fields above and
262 // should remain last (shifted by one more than the last value) 284 // should remain last (shifted by one more than the last value)
263 END = 1 << 4 285 END = 1 << 5
264 }; 286 };
265 287
266 // This variable records the status of three folder operations. 288 // This variable records the status of three folder operations.
267 uint32_t folder_operation_status = FolderOperationResult::SUCCESS; 289 uint32_t folder_operation_status = FolderOperationResult::SUCCESS;
268 290
269 base::ScopedClosureRunner log_operation_status_when_done(base::Bind( 291 base::ScopedClosureRunner log_operation_status_when_done(base::Bind(
270 [](uint32_t* folder_operation_status_ptr) { 292 [](uint32_t* folder_operation_status_ptr) {
271 UMA_HISTOGRAM_ENUMERATION("WinJumplist.DetailedFolderResults", 293 UMA_HISTOGRAM_ENUMERATION(
272 *folder_operation_status_ptr, 294 "WinJumplist.DetailedFolderResultsDeleteUpdated",
Ilya Sherman 2017/03/10 23:30:16 Optional nit: I'd suggest a simpler renaming, to "
chengx 2017/03/10 23:58:51 I know it is a bit long, but I will stick with thi
273 FolderOperationResult::END); 295 *folder_operation_status_ptr, FolderOperationResult::END);
274 }, 296 },
275 base::Unretained(&folder_operation_status))); 297 base::Unretained(&folder_operation_status)));
276 298
277 // If deletion of |icon_dir_old| fails, do not move |icon_dir| to 299 // If deletion of |icon_dir_old| fails, do not rename |icon_dir| to
278 // |icon_dir_old|, instead, delete |icon_dir| directly to avoid bloating 300 // |icon_dir_old|, instead, delete |icon_dir| directly to avoid bloating
279 // |icon_dir_old| by moving more things to it. 301 // |icon_dir_old| by moving more things to it.
280 if (!base::DeleteFile(icon_dir_old, true)) { 302 if (!base::DeleteFile(icon_dir_old, true)) {
281 folder_operation_status |= FolderOperationResult::DELETE_DEST_FAILED; 303 folder_operation_status |= FolderOperationResult::DELETE_DEST_FAILED;
282 // If deletion of |icon_dir| fails, exit early. This skips creating the same 304 // If deletion of any item in |icon_dir| fails, exit early. If deletion of
283 // directory and updating jumplist icons to avoid bloating the JumplistIcons 305 // all the items succeeds while only deletion of the dir fails, it is okay
284 // folder. 306 // to proceed. This skips creating the same directory and updating jumplist
307 // icons to avoid bloating the JumplistIcons folder.
285 if (!base::DeleteFile(icon_dir, true)) { 308 if (!base::DeleteFile(icon_dir, true)) {
286 folder_operation_status |= FolderOperationResult::DELETE_SRC_FAILED; 309 if (!::PathIsDirectoryEmpty(icon_dir.value().c_str())) {
287 return; 310 folder_operation_status |=
311 FolderOperationResult::DELETE_SRC_CONTENT_FAILED;
312 return;
313 } else {
314 folder_operation_status |= FolderOperationResult::DELETE_SRC_DIR_FAILED;
315 }
288 } 316 }
289 } else if (!base::Move(icon_dir, icon_dir_old)) { 317 } else if (!RenameDirectory(icon_dir, icon_dir_old)) {
290 folder_operation_status |= FolderOperationResult::MOVE_FAILED; 318 // If RenameDirectory() fails, delete |icon_dir| to avoid file accumulation
291 // If Move() fails, delete |icon_dir| to avoid file accumulation in this 319 // in this directory, which can eventually lead the folder to be huge.
292 // directory, which can eventually lead the folder to be huge. 320 folder_operation_status |= FolderOperationResult::RENAME_FAILED;
321 // If deletion of any item in |icon_dir| fails, exit early. If deletion of
322 // all the items succeeds while only deletion of the dir fails, it is okay
323 // to proceed. This skips creating the same directory and updating jumplist
324 // icons to avoid bloating the JumplistIcons folder.
293 if (!base::DeleteFile(icon_dir, true)) { 325 if (!base::DeleteFile(icon_dir, true)) {
294 folder_operation_status |= FolderOperationResult::DELETE_SRC_FAILED; 326 if (!::PathIsDirectoryEmpty(icon_dir.value().c_str())) {
295 return; 327 folder_operation_status |=
328 FolderOperationResult::DELETE_SRC_CONTENT_FAILED;
329 return;
330 } else {
331 folder_operation_status |= FolderOperationResult::DELETE_SRC_DIR_FAILED;
332 }
296 } 333 }
297 } 334 }
298 335
299 if (!base::CreateDirectory(icon_dir)) 336 if (!base::CreateDirectory(icon_dir))
300 folder_operation_status |= FolderOperationResult::CREATE_SRC_FAILED; 337 folder_operation_status |= FolderOperationResult::CREATE_SRC_FAILED;
301 338
302 // Create temporary icon files for shortcuts in the "Most Visited" category. 339 // Create temporary icon files for shortcuts in the "Most Visited" category.
303 CreateIconFiles(icon_dir, local_most_visited_pages); 340 CreateIconFiles(icon_dir, local_most_visited_pages);
304 341
305 // Create temporary icon files for shortcuts in the "Recently Closed" 342 // Create temporary icon files for shortcuts in the "Recently Closed"
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 void JumpList::TopSitesLoaded(history::TopSites* top_sites) { 670 void JumpList::TopSitesLoaded(history::TopSites* top_sites) {
634 } 671 }
635 672
636 void JumpList::TopSitesChanged(history::TopSites* top_sites, 673 void JumpList::TopSitesChanged(history::TopSites* top_sites,
637 ChangeReason change_reason) { 674 ChangeReason change_reason) {
638 top_sites->GetMostVisitedURLs( 675 top_sites->GetMostVisitedURLs(
639 base::Bind(&JumpList::OnMostVisitedURLsAvailable, 676 base::Bind(&JumpList::OnMostVisitedURLsAvailable,
640 weak_ptr_factory_.GetWeakPtr()), 677 weak_ptr_factory_.GetWeakPtr()),
641 false); 678 false);
642 } 679 }
OLDNEW
« no previous file with comments | « no previous file | tools/metrics/histograms/histograms.xml » ('j') | tools/metrics/histograms/histograms.xml » ('J')

Powered by Google App Engine
This is Rietveld 408576698