OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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/themes/theme_service.h" | 5 #include "chrome/browser/themes/theme_service.h" |
6 | 6 |
7 #include "base/json/json_reader.h" | 7 #include "base/file_util.h" |
| 8 #include "base/path_service.h" |
| 9 #include "chrome/browser/chrome_notification_types.h" |
8 #include "chrome/browser/extensions/extension_service_unittest.h" | 10 #include "chrome/browser/extensions/extension_service_unittest.h" |
| 11 #include "chrome/browser/extensions/unpacked_installer.h" |
9 #include "chrome/browser/managed_mode/managed_user_service.h" | 12 #include "chrome/browser/managed_mode/managed_user_service.h" |
10 #include "chrome/browser/managed_mode/managed_user_service_factory.h" | 13 #include "chrome/browser/managed_mode/managed_user_service_factory.h" |
11 #include "chrome/browser/themes/custom_theme_supplier.h" | 14 #include "chrome/browser/themes/custom_theme_supplier.h" |
12 #include "chrome/browser/themes/theme_service_factory.h" | 15 #include "chrome/browser/themes/theme_service_factory.h" |
| 16 #include "chrome/common/chrome_paths.h" |
13 #include "chrome/common/extensions/extension.h" | 17 #include "chrome/common/extensions/extension.h" |
14 #include "chrome/common/extensions/extension_manifest_constants.h" | 18 #include "chrome/common/extensions/extension_manifest_constants.h" |
15 #include "chrome/common/pref_names.h" | 19 #include "chrome/common/pref_names.h" |
16 #include "chrome/test/base/testing_browser_process.h" | 20 #include "chrome/test/base/testing_browser_process.h" |
17 #include "chrome/test/base/testing_profile.h" | 21 #include "chrome/test/base/testing_profile.h" |
18 #include "chrome/test/base/testing_profile_manager.h" | 22 #include "chrome/test/base/testing_profile_manager.h" |
| 23 #include "content/public/test/test_utils.h" |
19 #include "testing/gtest/include/gtest/gtest.h" | 24 #include "testing/gtest/include/gtest/gtest.h" |
20 | 25 |
21 namespace theme_service_internal { | 26 namespace theme_service_internal { |
22 | 27 |
23 class ThemeServiceTest : public ExtensionServiceTestBase { | 28 class ThemeServiceTest : public ExtensionServiceTestBase { |
24 public: | 29 public: |
25 ThemeServiceTest() { | 30 ThemeServiceTest() { |
26 manager_.reset( | 31 manager_.reset( |
27 new TestingProfileManager(TestingBrowserProcess::GetGlobal())); | 32 new TestingProfileManager(TestingBrowserProcess::GetGlobal())); |
28 } | 33 } |
29 virtual ~ThemeServiceTest() {} | 34 virtual ~ThemeServiceTest() {} |
30 | 35 |
31 scoped_refptr<extensions::Extension> MakeThemeExtension(base::FilePath path) { | 36 // Moves a minimal theme to |temp_dir_path| and unpacks it from that |
32 DictionaryValue source; | 37 // directory. |
33 source.SetString(extension_manifest_keys::kName, "theme"); | 38 std::string LoadUnpackedThemeAt(const base::FilePath& temp_dir) { |
34 source.Set(extension_manifest_keys::kTheme, new DictionaryValue()); | 39 base::FilePath dst_manifest_path = temp_dir.AppendASCII("manifest.json"); |
35 source.SetString(extension_manifest_keys::kUpdateURL, "http://foo.com"); | 40 base::FilePath test_data_dir; |
36 source.SetString(extension_manifest_keys::kVersion, "0.0.0.0"); | 41 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir)); |
37 std::string error; | 42 base::FilePath src_manifest_path = |
38 scoped_refptr<extensions::Extension> extension = | 43 test_data_dir.AppendASCII("extensions/theme_minimal/manifest.json"); |
39 extensions::Extension::Create( | 44 EXPECT_TRUE(base::CopyFile(src_manifest_path, dst_manifest_path)); |
40 path, extensions::Manifest::EXTERNAL_PREF_DOWNLOAD, | 45 |
41 source, extensions::Extension::NO_FLAGS, &error); | 46 scoped_refptr<extensions::UnpackedInstaller> installer( |
42 EXPECT_TRUE(extension.get()); | 47 extensions::UnpackedInstaller::Create(service_)); |
43 EXPECT_EQ("", error); | 48 content::WindowedNotificationObserver observer( |
44 return extension; | 49 chrome::NOTIFICATION_EXTENSION_LOADED, |
| 50 content::Source<Profile>(profile_.get())); |
| 51 installer->Load(temp_dir); |
| 52 observer.Wait(); |
| 53 |
| 54 std::string extension_id = |
| 55 content::Details<extensions::Extension>(observer.details())->id(); |
| 56 |
| 57 // Let the ThemeService finish creating the theme pack. |
| 58 base::MessageLoop::current()->RunUntilIdle(); |
| 59 |
| 60 return extension_id; |
| 61 } |
| 62 |
| 63 // Update the theme with |extension_id|. |
| 64 void UpdateUnpackedTheme(const std::string& extension_id) { |
| 65 int updated_notification = service_->IsExtensionEnabled(extension_id) ? |
| 66 chrome::NOTIFICATION_EXTENSION_LOADED : |
| 67 chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED; |
| 68 |
| 69 const base::FilePath& path = |
| 70 service_->GetInstalledExtension(extension_id)->path(); |
| 71 |
| 72 scoped_refptr<extensions::UnpackedInstaller> installer( |
| 73 extensions::UnpackedInstaller::Create(service_)); |
| 74 content::WindowedNotificationObserver observer(updated_notification, |
| 75 content::Source<Profile>(profile_.get())); |
| 76 installer->Load(path); |
| 77 observer.Wait(); |
| 78 |
| 79 // Let the ThemeService finish creating the theme pack. |
| 80 base::MessageLoop::current()->RunUntilIdle(); |
45 } | 81 } |
46 | 82 |
47 virtual void SetUp() { | 83 virtual void SetUp() { |
48 ExtensionServiceTestBase::SetUp(); | 84 ExtensionServiceTestBase::SetUp(); |
49 InitializeEmptyExtensionService(); | 85 InitializeEmptyExtensionService(); |
| 86 service_->Init(); |
50 bool success = manager_->SetUp(); | 87 bool success = manager_->SetUp(); |
51 ASSERT_TRUE(success); | 88 ASSERT_TRUE(success); |
52 } | 89 } |
53 | 90 |
54 const CustomThemeSupplier* get_theme_supplier(ThemeService* theme_service) { | 91 const CustomThemeSupplier* get_theme_supplier(ThemeService* theme_service) { |
55 return theme_service->get_theme_supplier(); | 92 return theme_service->get_theme_supplier(); |
56 } | 93 } |
57 | 94 |
58 TestingProfileManager* manager() { | 95 TestingProfileManager* manager() { |
59 return manager_.get(); | 96 return manager_.get(); |
60 } | 97 } |
61 | 98 |
62 private: | 99 private: |
63 scoped_ptr<TestingProfileManager> manager_; | 100 scoped_ptr<TestingProfileManager> manager_; |
64 }; | 101 }; |
65 | 102 |
66 // Installs then uninstalls a theme and makes sure that the ThemeService | 103 // Installs then uninstalls a theme and makes sure that the ThemeService |
67 // reverts to the default theme after the uninstall. | 104 // reverts to the default theme after the uninstall. |
68 TEST_F(ThemeServiceTest, ThemeInstallUninstall) { | 105 TEST_F(ThemeServiceTest, ThemeInstallUninstall) { |
69 base::ScopedTempDir temp_dir; | |
70 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | |
71 ThemeService* theme_service = | 106 ThemeService* theme_service = |
72 ThemeServiceFactory::GetForProfile(profile_.get()); | 107 ThemeServiceFactory::GetForProfile(profile_.get()); |
73 theme_service->UseDefaultTheme(); | 108 theme_service->UseDefaultTheme(); |
74 scoped_refptr<extensions::Extension> extension = | 109 // Let the ThemeService uninstall unused themes. |
75 MakeThemeExtension(temp_dir.path()); | |
76 service_->FinishInstallationForTest(extension.get()); | |
77 // Let ThemeService finish creating the theme pack. | |
78 base::MessageLoop::current()->RunUntilIdle(); | 110 base::MessageLoop::current()->RunUntilIdle(); |
| 111 |
| 112 base::ScopedTempDir temp_dir; |
| 113 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 114 const std::string& extension_id = LoadUnpackedThemeAt(temp_dir.path()); |
79 EXPECT_FALSE(theme_service->UsingDefaultTheme()); | 115 EXPECT_FALSE(theme_service->UsingDefaultTheme()); |
80 EXPECT_EQ(extension->id(), theme_service->GetThemeID()); | 116 EXPECT_EQ(extension_id, theme_service->GetThemeID()); |
81 | 117 |
82 // Now unload the extension, should revert to the default theme. | 118 // Now uninstall the extension, should revert to the default theme. |
83 service_->UnloadExtension(extension->id(), | 119 service_->UninstallExtension(extension_id, false, NULL); |
84 extension_misc::UNLOAD_REASON_UNINSTALL); | |
85 EXPECT_TRUE(theme_service->UsingDefaultTheme()); | 120 EXPECT_TRUE(theme_service->UsingDefaultTheme()); |
86 } | 121 } |
87 | 122 |
88 // Upgrades a theme and ensures that the ThemeService does not revert to the | 123 // Test that a theme extension is disabled when not in use. A theme may be |
89 // default theme. | 124 // installed but not in use if it there is an infobar to revert to the previous |
90 TEST_F(ThemeServiceTest, ThemeUpgrade) { | 125 // theme. |
91 base::ScopedTempDir temp_dir; | 126 TEST_F(ThemeServiceTest, DisableUnusedTheme) { |
92 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | |
93 ThemeService* theme_service = | 127 ThemeService* theme_service = |
94 ThemeServiceFactory::GetForProfile(profile_.get()); | 128 ThemeServiceFactory::GetForProfile(profile_.get()); |
95 theme_service->UseDefaultTheme(); | 129 theme_service->UseDefaultTheme(); |
96 scoped_refptr<extensions::Extension> extension = | 130 // Let the ThemeService uninstall unused themes. |
97 MakeThemeExtension(temp_dir.path()); | |
98 service_->FinishInstallationForTest(extension.get()); | |
99 // Let ThemeService finish creating the theme pack. | |
100 base::MessageLoop::current()->RunUntilIdle(); | 131 base::MessageLoop::current()->RunUntilIdle(); |
| 132 |
| 133 base::ScopedTempDir temp_dir1; |
| 134 ASSERT_TRUE(temp_dir1.CreateUniqueTempDir()); |
| 135 base::ScopedTempDir temp_dir2; |
| 136 ASSERT_TRUE(temp_dir2.CreateUniqueTempDir()); |
| 137 |
| 138 // 1) Installing a theme should disable the previously active theme. |
| 139 const std::string& extension1_id = LoadUnpackedThemeAt(temp_dir1.path()); |
101 EXPECT_FALSE(theme_service->UsingDefaultTheme()); | 140 EXPECT_FALSE(theme_service->UsingDefaultTheme()); |
102 EXPECT_EQ(extension->id(), theme_service->GetThemeID()); | 141 EXPECT_EQ(extension1_id, theme_service->GetThemeID()); |
| 142 EXPECT_TRUE(service_->IsExtensionEnabled(extension1_id)); |
103 | 143 |
104 // Now unload the extension, should revert to the default theme. | 144 // Show an infobar to prevent the current theme from being uninstalled. |
105 service_->UnloadExtension(extension->id(), | 145 theme_service->OnInfobarDisplayed(); |
106 extension_misc::UNLOAD_REASON_UPDATE); | 146 |
| 147 const std::string& extension2_id = LoadUnpackedThemeAt(temp_dir2.path()); |
| 148 EXPECT_EQ(extension2_id, theme_service->GetThemeID()); |
| 149 EXPECT_TRUE(service_->IsExtensionEnabled(extension2_id)); |
| 150 EXPECT_TRUE(service_->GetExtensionById(extension1_id, |
| 151 ExtensionService::INCLUDE_DISABLED)); |
| 152 |
| 153 // 2) Enabling a disabled theme extension should swap the current theme. |
| 154 service_->EnableExtension(extension1_id); |
| 155 base::MessageLoop::current()->RunUntilIdle(); |
| 156 EXPECT_EQ(extension1_id, theme_service->GetThemeID()); |
| 157 EXPECT_TRUE(service_->IsExtensionEnabled(extension1_id)); |
| 158 EXPECT_TRUE(service_->GetExtensionById(extension2_id, |
| 159 ExtensionService::INCLUDE_DISABLED)); |
| 160 |
| 161 // 3) Using SetTheme() with a disabled theme should enable and set the |
| 162 // theme. This is the case when the user reverts to the previous theme |
| 163 // via an infobar. |
| 164 const extensions::Extension* extension2 = |
| 165 service_->GetInstalledExtension(extension2_id); |
| 166 theme_service->SetTheme(extension2); |
| 167 base::MessageLoop::current()->RunUntilIdle(); |
| 168 EXPECT_EQ(extension2_id, theme_service->GetThemeID()); |
| 169 EXPECT_TRUE(service_->IsExtensionEnabled(extension2_id)); |
| 170 EXPECT_TRUE(service_->GetExtensionById(extension1_id, |
| 171 ExtensionService::INCLUDE_DISABLED)); |
| 172 |
| 173 // 4) Disabling the current theme extension should revert to the default theme |
| 174 // and uninstall any installed theme extensions. |
| 175 theme_service->OnInfobarDestroyed(); |
107 EXPECT_FALSE(theme_service->UsingDefaultTheme()); | 176 EXPECT_FALSE(theme_service->UsingDefaultTheme()); |
| 177 service_->DisableExtension(extension2_id, |
| 178 extensions::Extension::DISABLE_USER_ACTION); |
| 179 base::MessageLoop::current()->RunUntilIdle(); |
| 180 EXPECT_TRUE(theme_service->UsingDefaultTheme()); |
| 181 EXPECT_FALSE(service_->GetInstalledExtension(extension1_id)); |
| 182 EXPECT_FALSE(service_->GetInstalledExtension(extension2_id)); |
| 183 } |
| 184 |
| 185 // Test the ThemeService's behavior when a theme is upgraded. |
| 186 TEST_F(ThemeServiceTest, ThemeUpgrade) { |
| 187 // Setup. |
| 188 ThemeService* theme_service = |
| 189 ThemeServiceFactory::GetForProfile(profile_.get()); |
| 190 theme_service->UseDefaultTheme(); |
| 191 // Let the ThemeService uninstall unused themes. |
| 192 base::MessageLoop::current()->RunUntilIdle(); |
| 193 |
| 194 theme_service->OnInfobarDisplayed(); |
| 195 |
| 196 base::ScopedTempDir temp_dir1; |
| 197 ASSERT_TRUE(temp_dir1.CreateUniqueTempDir()); |
| 198 base::ScopedTempDir temp_dir2; |
| 199 ASSERT_TRUE(temp_dir2.CreateUniqueTempDir()); |
| 200 |
| 201 const std::string& extension1_id = LoadUnpackedThemeAt(temp_dir1.path()); |
| 202 const std::string& extension2_id = LoadUnpackedThemeAt(temp_dir2.path()); |
| 203 |
| 204 // Test the initial state. |
| 205 EXPECT_TRUE(service_->GetExtensionById(extension1_id, |
| 206 ExtensionService::INCLUDE_DISABLED)); |
| 207 EXPECT_EQ(extension2_id, theme_service->GetThemeID()); |
| 208 |
| 209 // 1) Upgrading the current theme should not revert to the default theme. |
| 210 content::WindowedNotificationObserver theme_change_observer( |
| 211 chrome::NOTIFICATION_BROWSER_THEME_CHANGED, |
| 212 content::Source<ThemeService>(theme_service)); |
| 213 UpdateUnpackedTheme(extension2_id); |
| 214 |
| 215 // The ThemeService should have sent an theme change notification even though |
| 216 // the id of the current theme did not change. |
| 217 theme_change_observer.Wait(); |
| 218 |
| 219 EXPECT_EQ(extension2_id, theme_service->GetThemeID()); |
| 220 EXPECT_TRUE(service_->GetExtensionById(extension1_id, |
| 221 ExtensionService::INCLUDE_DISABLED)); |
| 222 |
| 223 // 2) Upgrading a disabled theme should not change the current theme. |
| 224 UpdateUnpackedTheme(extension1_id); |
| 225 EXPECT_EQ(extension2_id, theme_service->GetThemeID()); |
| 226 EXPECT_TRUE(service_->GetExtensionById(extension1_id, |
| 227 ExtensionService::INCLUDE_DISABLED)); |
108 } | 228 } |
109 | 229 |
110 // Checks that managed users have their own default theme. | 230 // Checks that managed users have their own default theme. |
111 TEST_F(ThemeServiceTest, ManagedUserThemeReplacesDefaultTheme) { | 231 TEST_F(ThemeServiceTest, ManagedUserThemeReplacesDefaultTheme) { |
112 profile_->GetPrefs()->SetBoolean(prefs::kProfileIsManaged, true); | 232 profile_->GetPrefs()->SetBoolean(prefs::kProfileIsManaged, true); |
113 ThemeService* theme_service = | 233 ThemeService* theme_service = |
114 ThemeServiceFactory::GetForProfile(profile_.get()); | 234 ThemeServiceFactory::GetForProfile(profile_.get()); |
115 theme_service->UseDefaultTheme(); | 235 theme_service->UseDefaultTheme(); |
116 EXPECT_TRUE(theme_service->UsingDefaultTheme()); | 236 EXPECT_TRUE(theme_service->UsingDefaultTheme()); |
117 EXPECT_TRUE(get_theme_supplier(theme_service)); | 237 EXPECT_TRUE(get_theme_supplier(theme_service)); |
(...skipping 23 matching lines...) Expand all Loading... |
141 ThemeServiceFactory::GetForProfile(profile_.get()); | 261 ThemeServiceFactory::GetForProfile(profile_.get()); |
142 theme_service->UseDefaultTheme(); | 262 theme_service->UseDefaultTheme(); |
143 EXPECT_TRUE(theme_service->UsingDefaultTheme()); | 263 EXPECT_TRUE(theme_service->UsingDefaultTheme()); |
144 EXPECT_TRUE(get_theme_supplier(theme_service)); | 264 EXPECT_TRUE(get_theme_supplier(theme_service)); |
145 EXPECT_EQ(get_theme_supplier(theme_service)->get_theme_type(), | 265 EXPECT_EQ(get_theme_supplier(theme_service)->get_theme_type(), |
146 CustomThemeSupplier::MANAGED_USER_THEME); | 266 CustomThemeSupplier::MANAGED_USER_THEME); |
147 } | 267 } |
148 #endif | 268 #endif |
149 | 269 |
150 }; // namespace theme_service_internal | 270 }; // namespace theme_service_internal |
OLD | NEW |