Chromium Code Reviews| Index: chrome/browser/win/jumplist.cc |
| diff --git a/chrome/browser/win/jumplist.cc b/chrome/browser/win/jumplist.cc |
| index 3c114eeab9aa26465d4946a0390a3ba229b22062..3ffddb28132bb73173603422d8243bb7297391bb 100644 |
| --- a/chrome/browser/win/jumplist.cc |
| +++ b/chrome/browser/win/jumplist.cc |
| @@ -4,6 +4,9 @@ |
| #include "chrome/browser/win/jumplist.h" |
| +#include <Shlwapi.h> |
| +#include <windows.h> |
| + |
| #include "base/bind.h" |
| #include "base/bind_helpers.h" |
| #include "base/callback_helpers.h" |
| @@ -15,6 +18,7 @@ |
| #include "base/strings/string_util.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "base/threading/thread.h" |
| +#include "base/threading/thread_restrictions.h" |
| #include "base/trace_event/trace_event.h" |
| #include "chrome/browser/chrome_notification_types.h" |
| #include "chrome/browser/favicon/favicon_service_factory.h" |
| @@ -225,6 +229,22 @@ bool UpdateJumpList(const wchar_t* app_id, |
| return true; |
| } |
| +// Renames the directory |from_dir| to |to_path|. This method fails if any |
| +// process has a handle open in |from_dir| or if |to_path| exists. Base::Move() |
| +// tries to rename a file and if this fails, it tries copy-n-delete; This |
| +// RenameDirectory method only does the rename part. |
| +bool RenameDirectory(const base::FilePath& from_path, |
| + const base::FilePath& to_path) { |
| + base::ThreadRestrictions::AssertIOAllowed(); |
| + if (from_path.ReferencesParent() || to_path.ReferencesParent()) |
| + return false; |
| + if (from_path.value().length() >= MAX_PATH || |
| + to_path.value().length() >= MAX_PATH) { |
| + return false; |
| + } |
| + return MoveFileEx(from_path.value().c_str(), to_path.value().c_str(), 0) != 0; |
| +} |
| + |
| // Updates the jumplist, once all the data has been fetched. |
| void RunUpdateOnFileThread( |
| IncognitoModePrefs::Availability incognito_availability, |
| @@ -250,7 +270,8 @@ void RunUpdateOnFileThread( |
| // Delete the directory which contains old icon files, rename the current |
| // icon directory, and create a new directory which contains new JumpList |
| // icon files. |
| - base::FilePath icon_dir_old(icon_dir.value() + L"Old"); |
| + base::FilePath icon_dir_old = icon_dir.DirName().Append( |
| + icon_dir.BaseName().value() + FILE_PATH_LITERAL("Old")); |
| enum FolderOperationResult { |
| SUCCESS = 0, |
| @@ -274,25 +295,28 @@ void RunUpdateOnFileThread( |
| }, |
| base::Unretained(&folder_operation_status))); |
| - // If deletion of |icon_dir_old| fails, do not move |icon_dir| to |
| + // If deletion of |icon_dir_old| fails, do not rename |icon_dir| to |
| // |icon_dir_old|, instead, delete |icon_dir| directly to avoid bloating |
| // |icon_dir_old| by moving more things to it. |
| if (!base::DeleteFile(icon_dir_old, true)) { |
| folder_operation_status |= FolderOperationResult::DELETE_DEST_FAILED; |
| - // If deletion of |icon_dir| fails, exit early. This skips creating the same |
| - // directory and updating jumplist icons to avoid bloating the JumplistIcons |
| - // folder. |
| + // If deletion of any item in |icon_dir| fails, exit early. If deletion of |
| + // all the items succeeds while only deletion of the dir fails, it is okay |
| + // to proceed. This skips creating the same directory and updating jumplist |
| + // icons to avoid bloating the JumplistIcons folder. |
| if (!base::DeleteFile(icon_dir, true)) { |
| folder_operation_status |= FolderOperationResult::DELETE_SRC_FAILED; |
| - return; |
| + if (!::PathIsDirectoryEmpty(icon_dir.value().c_str())) |
|
grt (UTC plus 2)
2017/03/10 09:24:06
should you add something else to folder_operation_
chengx
2017/03/10 21:49:40
Sure, I have updated enum FolderOperationResult an
|
| + return; |
| } |
| - } else if (!base::Move(icon_dir, icon_dir_old)) { |
| + } else if (!RenameDirectory(icon_dir, icon_dir_old)) { |
| folder_operation_status |= FolderOperationResult::MOVE_FAILED; |
| - // If Move() fails, delete |icon_dir| to avoid file accumulation in this |
| - // directory, which can eventually lead the folder to be huge. |
| + // If RenameDirectory() fails, delete |icon_dir| to avoid file accumulation |
| + // in this directory, which can eventually lead the folder to be huge. |
| if (!base::DeleteFile(icon_dir, true)) { |
| folder_operation_status |= FolderOperationResult::DELETE_SRC_FAILED; |
| - return; |
| + if (!::PathIsDirectoryEmpty(icon_dir.value().c_str())) |
| + return; |
| } |
| } |