Commit fdc1a404 authored by Bret Sepulveda's avatar Bret Sepulveda Committed by Commit Bot

Migrate profile_shortcut_manager_win to use TaskScheduler.

This patch removes all references to BrowserThread::FILE and updates
the tests to handle the fact that the shortcut manager is now truly
multithreaded.

Bug: 689520
Change-Id: I31d145c6ac1685b150a57523d2268796a351f238
Reviewed-on: https://chromium-review.googlesource.com/582367Reviewed-by: default avatarRyan Hamilton <rch@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Commit-Queue: Bret Sepulveda <bsep@chromium.org>
Cr-Commit-Position: refs/heads/master@{#491513}
parent df86ed71
......@@ -47,6 +47,9 @@ class ProfileShortcutManager {
base::string16* name,
base::FilePath* icon_path) = 0;
// Any time a profile is created this class might do a lot of work in the
// background that's rarely important to unit tests.
static void DisableForUnitTests();
static bool IsFeatureEnabled();
static ProfileShortcutManager* Create(ProfileManager* manager);
......
......@@ -4,6 +4,8 @@
#include "chrome/browser/profiles/profile_shortcut_manager.h"
void ProfileShortcutManager::DisableForUnitTests() {}
// static
bool ProfileShortcutManager::IsFeatureEnabled() {
return false;
......
......@@ -7,15 +7,13 @@
#include "base/base_paths.h"
#include "base/files/file_util.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string16.h"
#include "base/task_runner_util.h"
#include "base/task_scheduler/post_task.h"
#include "base/test/scoped_path_override.h"
#include "base/test/scoped_task_environment.h"
#include "base/test/test_shortcut_win.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/win/shortcut.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_attributes_entry.h"
#include "chrome/browser/profiles/profile_attributes_storage.h"
......@@ -30,7 +28,6 @@
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/l10n/l10n_util.h"
......@@ -60,7 +57,7 @@ class ProfileShortcutManagerTest : public testing::Test {
}
void TearDown() override {
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
// Delete all profiles and ensure their shortcuts got removed.
const size_t num_profiles =
......@@ -71,7 +68,7 @@ class ProfileShortcutManagerTest : public testing::Test {
const base::FilePath profile_path = entry->GetPath();
base::string16 profile_name = entry->GetName();
profile_attributes_storage_->RemoveProfile(profile_path);
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
ASSERT_FALSE(ProfileShortcutExistsAtDefaultPath(profile_name));
// The icon file is not deleted until the profile directory is deleted.
const base::FilePath icon_path =
......@@ -98,7 +95,7 @@ class ProfileShortcutManagerTest : public testing::Test {
// Also create a non-badged shortcut for Chrome, which is conveniently done
// by |CreateProfileShortcut()| since there is only one profile.
profile_shortcut_manager_->CreateProfileShortcut(profile_1_path_);
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
// Verify that there's now a shortcut with no profile information.
ValidateNonProfileShortcut(location);
}
......@@ -123,6 +120,17 @@ class ProfileShortcutManagerTest : public testing::Test {
GetDefaultShortcutPathForProfile(profile_name));
}
// Posts a task to call base::win::ValidateShortcut on the COM thread.
void PostValidateShortcut(
const tracked_objects::Location& location,
const base::FilePath& shortcut_path,
const base::win::ShortcutProperties& expected_properties) {
base::CreateCOMSTATaskRunnerWithTraits({})->PostTask(
location, base::Bind(&base::win::ValidateShortcut, shortcut_path,
expected_properties));
RunTasksUntilIdle();
}
// Calls base::win::ValidateShortcut() with expected properties for the
// shortcut at |shortcut_path| for the profile at |profile_path|.
void ValidateProfileShortcutAtPath(const tracked_objects::Location& location,
......@@ -144,7 +152,7 @@ class ProfileShortcutManagerTest : public testing::Test {
expected_properties.set_arguments(
profiles::internal::CreateProfileShortcutFlags(profile_path));
expected_properties.set_icon(icon_path, 0);
base::win::ValidateShortcut(shortcut_path, expected_properties);
PostValidateShortcut(location, shortcut_path, expected_properties);
}
// Calls base::win::ValidateShortcut() with expected properties for
......@@ -167,7 +175,7 @@ class ProfileShortcutManagerTest : public testing::Test {
expected_properties.set_icon(GetExePath(), 0);
expected_properties.set_description(GetDistribution()->GetAppDescription());
expected_properties.set_dual_mode(false);
base::win::ValidateShortcut(shortcut_path, expected_properties);
PostValidateShortcut(location, shortcut_path, expected_properties);
}
void ValidateNonProfileShortcut(const tracked_objects::Location& location) {
......@@ -185,10 +193,24 @@ class ProfileShortcutManagerTest : public testing::Test {
std::string(), base::string16(), 0,
std::string());
profile_shortcut_manager_->CreateProfileShortcut(profile_path);
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
ValidateProfileShortcut(location, profile_name, profile_path);
}
// Posts a task to call ShellUtil::CreateOrUpdateShortcut on the COM thread.
void PostCreateOrUpdateShortcut(
const tracked_objects::Location& location,
const ShellUtil::ShortcutProperties& properties) {
base::PostTaskAndReplyWithResult(
base::CreateCOMSTATaskRunnerWithTraits({base::MayBlock()}).get(),
location,
base::Bind(&ShellUtil::CreateOrUpdateShortcut,
ShellUtil::SHORTCUT_LOCATION_DESKTOP, GetDistribution(),
properties, ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS),
base::Bind([](bool succeeded) { EXPECT_TRUE(succeeded); }));
RunTasksUntilIdle();
}
// Creates a regular (non-profile) desktop shortcut with the given name and
// returns its path. Fails the test if an error occurs.
base::FilePath CreateRegularShortcutWithName(
......@@ -202,9 +224,7 @@ class ProfileShortcutManagerTest : public testing::Test {
ShellUtil::ShortcutProperties properties(ShellUtil::CURRENT_USER);
product.AddDefaultShortcutProperties(GetExePath(), &properties);
properties.set_shortcut_name(shortcut_name);
EXPECT_TRUE(ShellUtil::CreateOrUpdateShortcut(
ShellUtil::SHORTCUT_LOCATION_DESKTOP, GetDistribution(), properties,
ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)) << location.ToString();
PostCreateOrUpdateShortcut(location, properties);
EXPECT_TRUE(base::PathExists(shortcut_path)) << location.ToString();
return shortcut_path;
......@@ -216,9 +236,7 @@ class ProfileShortcutManagerTest : public testing::Test {
installer::Product product(distribution);
ShellUtil::ShortcutProperties properties(ShellUtil::SYSTEM_LEVEL);
product.AddDefaultShortcutProperties(GetExePath(), &properties);
EXPECT_TRUE(ShellUtil::CreateOrUpdateShortcut(
ShellUtil::SHORTCUT_LOCATION_DESKTOP, distribution, properties,
ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS)) << location.ToString();
PostCreateOrUpdateShortcut(location, properties);
const base::FilePath system_level_shortcut_path =
GetSystemShortcutsDirectory().Append(distribution->GetShortcutName() +
installer::kLnkExt);
......@@ -235,7 +253,7 @@ class ProfileShortcutManagerTest : public testing::Test {
GetProfileAttributesWithPath(profile_path, &entry));
ASSERT_NE(entry->GetName(), new_profile_name);
entry->SetName(new_profile_name);
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
}
BrowserDistribution* GetDistribution() {
......@@ -266,7 +284,8 @@ class ProfileShortcutManagerTest : public testing::Test {
return system_shortcuts_directory;
}
content::TestBrowserThreadBundle thread_bundle_;
void RunTasksUntilIdle() { scoped_task_environment_.RunUntilIdle(); }
std::unique_ptr<TestingProfileManager> profile_manager_;
std::unique_ptr<ProfileShortcutManager> profile_shortcut_manager_;
ProfileAttributesStorage* profile_attributes_storage_;
......@@ -278,6 +297,9 @@ class ProfileShortcutManagerTest : public testing::Test {
base::FilePath profile_2_path_;
base::string16 profile_3_name_;
base::FilePath profile_3_path_;
private:
base::test::ScopedTaskEnvironment scoped_task_environment_;
};
TEST_F(ProfileShortcutManagerTest, ShortcutFilename) {
......@@ -355,7 +377,7 @@ TEST_F(ProfileShortcutManagerTest, CreateSecondProfileBadgesFirstShortcut) {
profile_attributes_storage_->AddProfile(profile_2_path_, profile_2_name_,
std::string(), base::string16(), 0,
std::string());
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
// Ensure that the second profile doesn't have a shortcut and that the first
// profile's shortcut got renamed and badged.
......@@ -369,7 +391,7 @@ TEST_F(ProfileShortcutManagerTest, DesktopShortcutsDeleteSecondToLast) {
// Delete one shortcut.
profile_attributes_storage_->RemoveProfile(profile_2_path_);
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
EXPECT_FALSE(ProfileShortcutExistsAtDefaultPath(profile_2_name_));
// Verify that the profile name has been removed from the remaining shortcut.
......@@ -394,7 +416,7 @@ TEST_F(ProfileShortcutManagerTest, DeleteSecondToLastProfileWithoutShortcut) {
// Delete the profile that doesn't have a shortcut.
profile_attributes_storage_->RemoveProfile(profile_1_path_);
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
// Verify that the remaining shortcut does not have a profile name.
ValidateNonProfileShortcut(FROM_HERE);
......@@ -418,7 +440,7 @@ TEST_F(ProfileShortcutManagerTest, DeleteSecondToLastProfileWithShortcut) {
// Delete the profile that has a shortcut.
profile_attributes_storage_->RemoveProfile(profile_2_path_);
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
// Verify that the remaining shortcut does not have a profile name.
ValidateNonProfileShortcut(FROM_HERE);
......@@ -453,7 +475,7 @@ TEST_F(ProfileShortcutManagerTest, DeleteOnlyProfileWithShortcuts) {
// Delete the third profile and check that its shortcut is gone and no
// shortcuts have been re-created.
profile_attributes_storage_->RemoveProfile(profile_3_path_);
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
ASSERT_FALSE(base::PathExists(profile_1_shortcut_path));
ASSERT_FALSE(base::PathExists(profile_2_shortcut_path));
ASSERT_FALSE(base::PathExists(profile_3_shortcut_path));
......@@ -465,7 +487,7 @@ TEST_F(ProfileShortcutManagerTest, DesktopShortcutsCreateSecond) {
// Delete one shortcut.
profile_attributes_storage_->RemoveProfile(profile_2_path_);
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
// Verify that a default shortcut exists (no profile name/avatar).
ValidateNonProfileShortcut(FROM_HERE);
......@@ -494,7 +516,7 @@ TEST_F(ProfileShortcutManagerTest, RenamedDesktopShortcuts) {
// Ensure that a new shortcut does not get made if the old one was renamed.
profile_shortcut_manager_->CreateProfileShortcut(profile_2_path_);
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
EXPECT_FALSE(ProfileShortcutExistsAtDefaultPath(profile_2_name_));
ValidateProfileShortcutAtPath(FROM_HERE, profile_2_shortcut_path_2,
profile_2_path_);
......@@ -503,7 +525,7 @@ TEST_F(ProfileShortcutManagerTest, RenamedDesktopShortcuts) {
ASSERT_TRUE(base::DeleteFile(profile_2_shortcut_path_2, false));
EXPECT_FALSE(base::PathExists(profile_2_shortcut_path_2));
profile_shortcut_manager_->CreateProfileShortcut(profile_2_path_);
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
ValidateProfileShortcut(FROM_HERE, profile_2_name_, profile_2_path_);
}
......@@ -532,7 +554,7 @@ TEST_F(ProfileShortcutManagerTest, RenamedDesktopShortcutsGetDeleted) {
// Delete the profile and ensure both shortcuts were also deleted.
profile_attributes_storage_->RemoveProfile(profile_2_path_);
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
EXPECT_FALSE(base::PathExists(profile_2_shortcut_path_1));
EXPECT_FALSE(base::PathExists(profile_2_shortcut_path_2));
ValidateNonProfileShortcutAtPath(FROM_HERE,
......@@ -630,7 +652,7 @@ TEST_F(ProfileShortcutManagerTest, RemoveProfileShortcuts) {
// Delete shortcuts for profile 1 and ensure that they got deleted while the
// shortcuts for profile 2 were kept.
profile_shortcut_manager_->RemoveProfileShortcuts(profile_1_path_);
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
EXPECT_FALSE(base::PathExists(profile_1_shortcut_path_1));
EXPECT_FALSE(base::PathExists(profile_1_shortcut_path_2));
ValidateProfileShortcutAtPath(FROM_HERE, profile_2_shortcut_path_1,
......@@ -653,7 +675,7 @@ TEST_F(ProfileShortcutManagerTest, HasProfileShortcuts) {
// Profile 2 should have a shortcut initially.
profile_shortcut_manager_->HasProfileShortcuts(profile_2_path_, callback);
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
EXPECT_TRUE(result.has_shortcuts);
// Delete the shortcut and check that the function returns false.
......@@ -662,7 +684,7 @@ TEST_F(ProfileShortcutManagerTest, HasProfileShortcuts) {
ASSERT_TRUE(base::DeleteFile(profile_2_shortcut_path, false));
EXPECT_FALSE(base::PathExists(profile_2_shortcut_path));
profile_shortcut_manager_->HasProfileShortcuts(profile_2_path_, callback);
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
EXPECT_FALSE(result.has_shortcuts);
}
......@@ -674,7 +696,7 @@ TEST_F(ProfileShortcutManagerTest, ProfileShortcutsWithSystemLevelShortcut) {
profile_attributes_storage_->AddProfile(profile_1_path_, profile_1_name_,
std::string(), base::string16(), 0,
std::string());
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
ASSERT_EQ(1u, profile_attributes_storage_->GetNumberOfProfiles());
// Ensure system-level continues to exist and user-level was not created.
......@@ -693,7 +715,7 @@ TEST_F(ProfileShortcutManagerTest, ProfileShortcutsWithSystemLevelShortcut) {
profile_attributes_storage_->AddProfile(profile_3_path_, profile_3_name_,
std::string(), base::string16(), 0,
std::string());
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
EXPECT_FALSE(ProfileShortcutExistsAtDefaultPath(profile_3_name_));
// Ensure that changing the avatar icon and the name does not result in a
......@@ -702,12 +724,12 @@ TEST_F(ProfileShortcutManagerTest, ProfileShortcutsWithSystemLevelShortcut) {
ASSERT_TRUE(profile_attributes_storage_->
GetProfileAttributesWithPath(profile_3_path_, &entry_3));
entry_3->SetAvatarIconIndex(3u);
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
EXPECT_FALSE(ProfileShortcutExistsAtDefaultPath(profile_3_name_));
const base::string16 new_profile_3_name = L"New Name 3";
entry_3->SetName(new_profile_3_name);
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
EXPECT_FALSE(ProfileShortcutExistsAtDefaultPath(profile_3_name_));
EXPECT_FALSE(ProfileShortcutExistsAtDefaultPath(new_profile_3_name));
......@@ -717,7 +739,7 @@ TEST_F(ProfileShortcutManagerTest, ProfileShortcutsWithSystemLevelShortcut) {
ASSERT_TRUE(profile_attributes_storage_->
GetProfileAttributesWithPath(profile_2_path_, &entry_2));
entry_2->SetName(new_profile_2_name);
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
EXPECT_FALSE(ProfileShortcutExistsAtDefaultPath(profile_2_name_));
ValidateProfileShortcut(FROM_HERE, new_profile_2_name, profile_2_path_);
}
......@@ -732,7 +754,7 @@ TEST_F(ProfileShortcutManagerTest,
// Delete a profile and verify that only the system-level shortcut still
// exists.
profile_attributes_storage_->RemoveProfile(profile_1_path_);
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
EXPECT_TRUE(base::PathExists(system_level_shortcut_path));
EXPECT_FALSE(ProfileShortcutExistsAtDefaultPath(base::string16()));
......@@ -761,7 +783,7 @@ TEST_F(ProfileShortcutManagerTest,
// shortcut creation path in |DeleteDesktopShortcuts()|, which is
// not covered by the |DeleteSecondToLastProfileWithSystemLevelShortcut| test.
profile_attributes_storage_->RemoveProfile(profile_2_path_);
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
// Verify that only the system-level shortcut still exists.
EXPECT_TRUE(base::PathExists(system_level_shortcut_path));
......@@ -782,7 +804,7 @@ TEST_F(ProfileShortcutManagerTest, CreateProfileIcon) {
EXPECT_FALSE(base::PathExists(icon_path));
profile_shortcut_manager_->CreateOrUpdateProfileIcon(profile_1_path_);
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
EXPECT_TRUE(base::PathExists(icon_path));
}
......@@ -813,7 +835,7 @@ TEST_F(ProfileShortcutManagerTest, UnbadgeProfileIconOnDeletion) {
// Deleting the default profile will unbadge the new profile's icon and should
// result in an icon that is identical to the unbadged default profile icon.
profile_attributes_storage_->RemoveProfile(profile_1_path_);
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
std::string unbadged_icon_2;
EXPECT_TRUE(base::ReadFileToString(icon_path_2, &unbadged_icon_2));
......@@ -840,7 +862,7 @@ TEST_F(ProfileShortcutManagerTest, ProfileIconOnAvatarChange) {
ASSERT_TRUE(profile_attributes_storage_->
GetProfileAttributesWithPath(profile_1_path_, &entry_1));
entry_1->SetAvatarIconIndex(1u);
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
std::string new_badged_icon_1;
EXPECT_TRUE(base::ReadFileToString(icon_path_1, &new_badged_icon_1));
......@@ -848,7 +870,7 @@ TEST_F(ProfileShortcutManagerTest, ProfileIconOnAvatarChange) {
// Ensure the new icon is not the unbadged icon.
profile_attributes_storage_->RemoveProfile(profile_2_path_);
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
std::string unbadged_icon_1;
EXPECT_TRUE(base::ReadFileToString(icon_path_1, &unbadged_icon_1));
......@@ -856,7 +878,7 @@ TEST_F(ProfileShortcutManagerTest, ProfileIconOnAvatarChange) {
// Ensure the icon doesn't change on avatar change without 2 profiles.
entry_1->SetAvatarIconIndex(1u);
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
std::string unbadged_icon_1_a;
EXPECT_TRUE(base::ReadFileToString(icon_path_1, &unbadged_icon_1_a));
......@@ -1002,7 +1024,7 @@ TEST_F(ProfileShortcutManagerTest, ShortcutsForProfilesWithIdenticalNames) {
// Delete profile1.
profile_attributes_storage_->RemoveProfile(profile_1_path_);
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
EXPECT_FALSE(ProfileShortcutExistsAtDefaultPath(new_profile_1_name));
// Check that nothing is changed for profile2 and profile3.
ValidateProfileShortcut(FROM_HERE, profile_2_name_, profile_2_path_);
......@@ -1015,7 +1037,7 @@ TEST_F(ProfileShortcutManagerTest, ShortcutsForProfilesWithIdenticalNames) {
GetDefaultShortcutPathForProfile(profile_2_name_)));
EXPECT_TRUE(base::PathExists(profile_3_shortcut_path));
profile_attributes_storage_->RemoveProfile(profile_2_path_);
base::RunLoop().RunUntilIdle();
RunTasksUntilIdle();
EXPECT_FALSE(base::PathExists(
GetDefaultShortcutPathForProfile(profile_2_name_)));
// Only profile3 exists. There should be non-profile shortcut only.
......
......@@ -22,6 +22,8 @@
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task_runner_util.h"
#include "base/task_scheduler/post_task.h"
#include "base/win/shortcut.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
......@@ -173,13 +175,10 @@ base::FilePath CreateOrUpdateShortcutIconForProfile(
const base::FilePath& profile_path,
const SkBitmap& avatar_bitmap_1x,
const SkBitmap& avatar_bitmap_2x) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
base::ThreadRestrictions::AssertIOAllowed();
if (!base::PathExists(profile_path)) {
LOG(ERROR) << "Profile directory " << profile_path.value()
<< " did not exist when trying to create profile icon";
if (!base::PathExists(profile_path))
return base::FilePath();
}
std::unique_ptr<gfx::ImageFamily> family = GetAppIconImageFamily();
if (!family)
......@@ -221,11 +220,8 @@ base::FilePath CreateOrUpdateShortcutIconForProfile(
const bool had_icon = base::PathExists(icon_path);
if (!IconUtil::CreateIconFileFromImageFamily(badged_bitmaps, icon_path)) {
// This can happen in theory if the profile directory is deleted between the
// beginning of this function and here; however this is extremely unlikely
// and this check will help catch any regression where this call would start
// failing constantly.
NOTREACHED();
// This can happen if the profile directory is deleted between the beginning
// of this function and here.
return base::FilePath();
}
......@@ -283,7 +279,7 @@ base::FilePath ConvertToLongPath(const base::FilePath& path) {
bool IsChromeShortcut(const base::FilePath& path,
const base::FilePath& chrome_exe,
base::string16* command_line) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
base::ThreadRestrictions::AssertIOAllowed();
if (path.Extension() != installer::kLnkExt)
return false;
......@@ -363,8 +359,7 @@ bool RenameDesktopShortcut(const base::FilePath& old_shortcut_path,
return true;
}
// Renames an existing Chrome desktop profile shortcut. Must be called on the
// FILE thread.
// Renames an existing Chrome desktop profile shortcut.
// |profile_shortcuts| are Chrome desktop shortcuts for the profile (there can
// be several).
// |desktop_contents| is the collection of all user desktop shortcuts
......@@ -379,7 +374,7 @@ void RenameChromeDesktopShortcutForProfile(
std::set<base::FilePath>* desktop_contents) {
DCHECK(profile_shortcuts);
DCHECK(desktop_contents);
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
base::ThreadRestrictions::AssertIOAllowed();
base::FilePath user_shortcuts_directory;
base::FilePath system_shortcuts_directory;
......@@ -480,11 +475,11 @@ struct CreateOrUpdateShortcutsParams {
// Updates all desktop shortcuts for the given profile to have the specified
// parameters. If |params.create_mode| is CREATE_WHEN_NONE_FOUND, a new shortcut
// is created if no existing ones were found. Whether non-profile shortcuts
// should be updated is specified by |params.action|. Must be called on the FILE
// thread.
// should be updated is specified by |params.action|. File and COM operations
// must be allowed on the calling thread.
void CreateOrUpdateDesktopShortcutsAndIconForProfile(
const CreateOrUpdateShortcutsParams& params) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
base::ThreadRestrictions::AssertIOAllowed();
const base::FilePath shortcut_icon =
CreateOrUpdateShortcutIconForProfile(params.profile_path,
......@@ -585,10 +580,10 @@ bool ChromeDesktopShortcutsExist(const base::FilePath& chrome_exe) {
// Deletes all desktop shortcuts for the specified profile. If
// |ensure_shortcuts_remain| is true, then a regular non-profile shortcut will
// be created if this function would otherwise delete the last Chrome desktop
// shortcut(s). Must be called on the FILE thread.
// shortcut(s). File and COM operations must be allowed on the calling thread.
void DeleteDesktopShortcuts(const base::FilePath& profile_path,
bool ensure_shortcuts_remain) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
base::ThreadRestrictions::AssertIOAllowed();
base::FilePath chrome_exe;
if (!PathService::Get(base::FILE_EXE, &chrome_exe)) {
......@@ -632,9 +627,10 @@ void DeleteDesktopShortcuts(const base::FilePath& profile_path,
}
// Returns true if profile at |profile_path| has any shortcuts. Does not
// consider non-profile shortcuts. Must be called on the FILE thread.
// consider non-profile shortcuts. File and COM operations must be allowed on
// the calling thread.
bool HasAnyProfileShortcuts(const base::FilePath& profile_path) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
base::ThreadRestrictions::AssertIOAllowed();
base::FilePath chrome_exe;
if (!PathService::Get(base::FILE_EXE, &chrome_exe)) {
......@@ -778,8 +774,19 @@ base::string16 CreateProfileShortcutFlags(const base::FilePath& profile_path) {
} // namespace internal
} // namespace profiles
namespace {
bool disabled_for_unit_tests = false;
}
void ProfileShortcutManager::DisableForUnitTests() {
disabled_for_unit_tests = true;
}
// static
bool ProfileShortcutManager::IsFeatureEnabled() {
if (disabled_for_unit_tests)
return false;
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(switches::kEnableProfileShortcutManager))
return true;
......@@ -830,17 +837,17 @@ void ProfileShortcutManagerWin::CreateProfileShortcut(
void ProfileShortcutManagerWin::RemoveProfileShortcuts(
const base::FilePath& profile_path) {
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
base::Bind(&DeleteDesktopShortcuts, profile_path, false));
base::CreateCOMSTATaskRunnerWithTraits({base::MayBlock()})
->PostTask(FROM_HERE,
base::Bind(&DeleteDesktopShortcuts, profile_path, false));
}
void ProfileShortcutManagerWin::HasProfileShortcuts(
const base::FilePath& profile_path,
const base::Callback<void(bool)>& callback) {
BrowserThread::PostTaskAndReplyWithResult(
BrowserThread::FILE, FROM_HERE,
base::Bind(&HasAnyProfileShortcuts, profile_path), callback);
base::PostTaskAndReplyWithResult(
base::CreateCOMSTATaskRunnerWithTraits({base::MayBlock()}).get(),
FROM_HERE, base::Bind(&HasAnyProfileShortcuts, profile_path), callback);
}
void ProfileShortcutManagerWin::GetShortcutProperties(
......@@ -905,10 +912,9 @@ void ProfileShortcutManagerWin::OnProfileWasRemoved(
IGNORE_NON_PROFILE_SHORTCUTS);
}
BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
base::Bind(&DeleteDesktopShortcuts,
profile_path,
deleting_down_to_last_profile));
base::CreateCOMSTATaskRunnerWithTraits({base::MayBlock()})
->PostTask(FROM_HERE, base::Bind(&DeleteDesktopShortcuts, profile_path,
deleting_down_to_last_profile));
}
void ProfileShortcutManagerWin::OnProfileNameChanged(
......@@ -996,14 +1002,15 @@ void ProfileShortcutManagerWin::CreateOrUpdateShortcutsForProfileAtPath(
profiles::GetDefaultAvatarIconResourceIDAtIndex(icon_index);
const int resource_id_2x = kProfileAvatarIconResources2x[icon_index];
// Make a copy of the SkBitmaps to ensure that we can safely use the image
// data on the FILE thread.
// data on the thread we post to.
params.avatar_image_1x = GetImageResourceSkBitmapCopy(resource_id_1x);
params.avatar_image_2x = GetImageResourceSkBitmapCopy(resource_id_2x);
}
}
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
base::Bind(&CreateOrUpdateDesktopShortcutsAndIconForProfile, params));
base::CreateCOMSTATaskRunnerWithTraits({base::MayBlock()})
->PostTask(
FROM_HERE,
base::Bind(&CreateOrUpdateDesktopShortcutsAndIconForProfile, params));
entry->SetShortcutName(params.profile_name);
}
......
......@@ -10,6 +10,7 @@
#include "base/process/process_handle.h"
#include "build/build_config.h"
#include "chrome/browser/chrome_content_browser_client.h"
#include "chrome/browser/profiles/profile_shortcut_manager.h"
#include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h"
#include "chrome/browser/update_client/chrome_update_query_params_delegate.h"
#include "chrome/common/chrome_content_client.h"
......@@ -112,6 +113,7 @@ void ChromeUnitTestSuite::Initialize() {
InitializeResourceBundle();
base::DiscardableMemoryAllocator::SetInstance(&discardable_memory_allocator_);
ProfileShortcutManager::DisableForUnitTests();
}
void ChromeUnitTestSuite::Shutdown() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment