| 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/command_line.h" |
| 7 #include "base/files/file_util.h" | 8 #include "base/files/file_util.h" |
| 8 #include "base/macros.h" | 9 #include "base/macros.h" |
| 9 #include "base/path_service.h" | 10 #include "base/path_service.h" |
| 10 #include "build/build_config.h" | 11 #include "build/build_config.h" |
| 11 #include "chrome/browser/chrome_notification_types.h" | 12 #include "chrome/browser/chrome_notification_types.h" |
| 12 #include "chrome/browser/extensions/extension_service.h" | 13 #include "chrome/browser/extensions/extension_service.h" |
| 13 #include "chrome/browser/extensions/extension_service_test_base.h" | 14 #include "chrome/browser/extensions/extension_service_test_base.h" |
| 14 #include "chrome/browser/extensions/unpacked_installer.h" | 15 #include "chrome/browser/extensions/unpacked_installer.h" |
| 15 #include "chrome/browser/themes/custom_theme_supplier.h" | 16 #include "chrome/browser/themes/custom_theme_supplier.h" |
| 16 #include "chrome/browser/themes/theme_properties.h" | 17 #include "chrome/browser/themes/theme_properties.h" |
| 17 #include "chrome/browser/themes/theme_service_factory.h" | 18 #include "chrome/browser/themes/theme_service_factory.h" |
| 18 #include "chrome/common/chrome_paths.h" | 19 #include "chrome/common/chrome_paths.h" |
| 19 #include "chrome/common/pref_names.h" | 20 #include "chrome/common/pref_names.h" |
| 20 #include "chrome/test/base/testing_browser_process.h" | 21 #include "chrome/test/base/testing_browser_process.h" |
| 21 #include "chrome/test/base/testing_profile.h" | 22 #include "chrome/test/base/testing_profile.h" |
| 22 #include "chrome/test/base/testing_profile_manager.h" | 23 #include "chrome/test/base/testing_profile_manager.h" |
| 23 #include "content/public/browser/notification_observer.h" | 24 #include "content/public/browser/notification_observer.h" |
| 24 #include "content/public/browser/notification_registrar.h" | 25 #include "content/public/browser/notification_registrar.h" |
| 25 #include "content/public/test/test_utils.h" | 26 #include "content/public/test/test_utils.h" |
| 26 #include "extensions/browser/extension_registry.h" | 27 #include "extensions/browser/extension_registry.h" |
| 27 #include "extensions/browser/test_extension_registry_observer.h" | 28 #include "extensions/browser/test_extension_registry_observer.h" |
| 28 #include "extensions/browser/uninstall_reason.h" | 29 #include "extensions/browser/uninstall_reason.h" |
| 29 #include "extensions/common/extension.h" | 30 #include "extensions/common/extension.h" |
| 30 #include "testing/gtest/include/gtest/gtest.h" | 31 #include "testing/gtest/include/gtest/gtest.h" |
| 31 #include "ui/base/material_design/material_design_controller.h" | 32 #include "ui/base/material_design/material_design_controller.h" |
| 33 #include "ui/base/test/material_design_controller_test_api.h" |
| 34 #include "ui/base/ui_base_switches.h" |
| 32 | 35 |
| 33 #if defined(ENABLE_SUPERVISED_USERS) | 36 #if defined(ENABLE_SUPERVISED_USERS) |
| 34 #include "chrome/browser/supervised_user/supervised_user_service.h" | 37 #include "chrome/browser/supervised_user/supervised_user_service.h" |
| 35 #include "chrome/browser/supervised_user/supervised_user_service_factory.h" | 38 #include "chrome/browser/supervised_user/supervised_user_service_factory.h" |
| 36 #endif | 39 #endif |
| 37 | 40 |
| 38 using extensions::ExtensionRegistry; | 41 using extensions::ExtensionRegistry; |
| 39 | 42 |
| 40 namespace theme_service_internal { | 43 namespace theme_service_internal { |
| 41 | 44 |
| 42 class ThemeServiceTest : public extensions::ExtensionServiceTestBase { | 45 class ThemeServiceTest : public extensions::ExtensionServiceTestBase { |
| 43 public: | 46 public: |
| 44 ThemeServiceTest() : is_supervised_(false), | 47 ThemeServiceTest() : is_supervised_(false), |
| 45 registry_(NULL) {} | 48 registry_(NULL) {} |
| 46 ~ThemeServiceTest() override {} | 49 ~ThemeServiceTest() override {} |
| 47 | 50 |
| 51 void SetUp() override { |
| 52 extensions::ExtensionServiceTestBase::SetUp(); |
| 53 extensions::ExtensionServiceTestBase::ExtensionServiceInitParams params = |
| 54 CreateDefaultInitParams(); |
| 55 params.profile_is_supervised = is_supervised_; |
| 56 InitializeExtensionService(params); |
| 57 service_->Init(); |
| 58 registry_ = ExtensionRegistry::Get(profile_.get()); |
| 59 ASSERT_TRUE(registry_); |
| 60 } |
| 61 |
| 48 // Moves a minimal theme to |temp_dir_path| and unpacks it from that | 62 // Moves a minimal theme to |temp_dir_path| and unpacks it from that |
| 49 // directory. | 63 // directory. |
| 50 std::string LoadUnpackedThemeAt(const base::FilePath& temp_dir) { | 64 std::string LoadUnpackedThemeAt(const base::FilePath& temp_dir) { |
| 51 base::FilePath dst_manifest_path = temp_dir.AppendASCII("manifest.json"); | 65 base::FilePath dst_manifest_path = temp_dir.AppendASCII("manifest.json"); |
| 52 base::FilePath test_data_dir; | 66 base::FilePath test_data_dir; |
| 53 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir)); | 67 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir)); |
| 54 base::FilePath src_manifest_path = | 68 base::FilePath src_manifest_path = |
| 55 test_data_dir.AppendASCII("extensions/theme_minimal/manifest.json"); | 69 test_data_dir.AppendASCII("extensions/theme_minimal/manifest.json"); |
| 56 EXPECT_TRUE(base::CopyFile(src_manifest_path, dst_manifest_path)); | 70 EXPECT_TRUE(base::CopyFile(src_manifest_path, dst_manifest_path)); |
| 57 | 71 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 85 extensions::NOTIFICATION_EXTENSION_UPDATE_DISABLED, | 99 extensions::NOTIFICATION_EXTENSION_UPDATE_DISABLED, |
| 86 content::Source<Profile>(profile_.get())); | 100 content::Source<Profile>(profile_.get())); |
| 87 installer->Load(path); | 101 installer->Load(path); |
| 88 observer.Wait(); | 102 observer.Wait(); |
| 89 } | 103 } |
| 90 | 104 |
| 91 // Let the ThemeService finish creating the theme pack. | 105 // Let the ThemeService finish creating the theme pack. |
| 92 base::MessageLoop::current()->RunUntilIdle(); | 106 base::MessageLoop::current()->RunUntilIdle(); |
| 93 } | 107 } |
| 94 | 108 |
| 95 void SetUp() override { | |
| 96 extensions::ExtensionServiceTestBase::SetUp(); | |
| 97 extensions::ExtensionServiceTestBase::ExtensionServiceInitParams params = | |
| 98 CreateDefaultInitParams(); | |
| 99 params.profile_is_supervised = is_supervised_; | |
| 100 InitializeExtensionService(params); | |
| 101 service_->Init(); | |
| 102 registry_ = ExtensionRegistry::Get(profile_.get()); | |
| 103 ASSERT_TRUE(registry_); | |
| 104 } | |
| 105 | |
| 106 const CustomThemeSupplier* get_theme_supplier(ThemeService* theme_service) { | 109 const CustomThemeSupplier* get_theme_supplier(ThemeService* theme_service) { |
| 107 return theme_service->get_theme_supplier(); | 110 return theme_service->get_theme_supplier(); |
| 108 } | 111 } |
| 109 | 112 |
| 113 // Alpha blends a non-opaque foreground color against an opaque background. |
| 114 // This is not the same as color_utils::AlphaBlend() since it gets the opacity |
| 115 // from the foreground color and then does not blend the two colors' alpha |
| 116 // values together. |
| 117 static SkColor AlphaBlend(SkColor foreground, SkColor background) { |
| 118 return color_utils::AlphaBlend(SkColorSetA(foreground, SK_AlphaOPAQUE), |
| 119 background, SkColorGetA(foreground)); |
| 120 } |
| 121 |
| 122 // Returns the separator color as the opaque result of blending it atop the |
| 123 // frame color (which is the color we use when calculating the contrast of the |
| 124 // separator with the tab and frame colors). |
| 125 static SkColor GetSeparatorColor(SkColor tab_color, SkColor frame_color) { |
| 126 return AlphaBlend(ThemeService::GetSeparatorColor(tab_color, frame_color), |
| 127 frame_color); |
| 128 } |
| 129 |
| 110 protected: | 130 protected: |
| 111 bool is_supervised_; | 131 bool is_supervised_; |
| 112 ExtensionRegistry* registry_; | 132 ExtensionRegistry* registry_; |
| 113 }; | 133 }; |
| 114 | 134 |
| 115 // Installs then uninstalls a theme and makes sure that the ThemeService | 135 // Installs then uninstalls a theme and makes sure that the ThemeService |
| 116 // reverts to the default theme after the uninstall. | 136 // reverts to the default theme after the uninstall. |
| 117 TEST_F(ThemeServiceTest, ThemeInstallUninstall) { | 137 TEST_F(ThemeServiceTest, ThemeInstallUninstall) { |
| 118 ThemeService* theme_service = | 138 ThemeService* theme_service = |
| 119 ThemeServiceFactory::GetForProfile(profile_.get()); | 139 ThemeServiceFactory::GetForProfile(profile_.get()); |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 369 ThemeServiceFactory::GetForProfile(profile_.get()); | 389 ThemeServiceFactory::GetForProfile(profile_.get()); |
| 370 theme_service->UseDefaultTheme(); | 390 theme_service->UseDefaultTheme(); |
| 371 EXPECT_TRUE(theme_service->UsingDefaultTheme()); | 391 EXPECT_TRUE(theme_service->UsingDefaultTheme()); |
| 372 EXPECT_TRUE(get_theme_supplier(theme_service)); | 392 EXPECT_TRUE(get_theme_supplier(theme_service)); |
| 373 EXPECT_EQ(get_theme_supplier(theme_service)->get_theme_type(), | 393 EXPECT_EQ(get_theme_supplier(theme_service)->get_theme_type(), |
| 374 CustomThemeSupplier::SUPERVISED_USER_THEME); | 394 CustomThemeSupplier::SUPERVISED_USER_THEME); |
| 375 } | 395 } |
| 376 #endif // defined(OS_LINUX) && !defined(OS_CHROMEOS) | 396 #endif // defined(OS_LINUX) && !defined(OS_CHROMEOS) |
| 377 #endif // defined(ENABLE_SUPERVISED_USERS) | 397 #endif // defined(ENABLE_SUPERVISED_USERS) |
| 378 | 398 |
| 399 #if !defined(OS_MACOSX) // Mac uses different colors than other platforms. |
| 400 // Simple class to run tests in material design mode. |
| 401 class ThemeServiceMaterialDesignTest : public ThemeServiceTest { |
| 402 public: |
| 403 void SetUp() override { |
| 404 ThemeServiceTest::SetUp(); |
| 405 ui::test::MaterialDesignControllerTestAPI::SetMode( |
| 406 ui::MaterialDesignController::MATERIAL_NORMAL); |
| 407 } |
| 408 |
| 409 void TearDown() override { |
| 410 ThemeServiceTest::TearDown(); |
| 411 ui::test::MaterialDesignControllerTestAPI::UninitializeMode(); |
| 412 } |
| 413 }; |
| 414 |
| 415 // Check that the function which computes the separator color behaves as |
| 416 // expected for a variety of inputs. We run in material design mode so we can |
| 417 // use the material normal and incognito color combinations, which differ from |
| 418 // each other in ways that are interesting to test. |
| 419 TEST_F(ThemeServiceMaterialDesignTest, SeparatorColor) { |
| 420 // Ensure Windows 10 machines use the built-in default colors rather than the |
| 421 // current system native colors. |
| 422 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| 423 switches::kDisableDwmComposition); |
| 424 |
| 425 // Check that the TOOLBAR_TOP_SEPARATOR color is the same whether we ask the |
| 426 // theme provider or compute it manually. |
| 427 const ui::ThemeProvider& theme_provider = |
| 428 ThemeService::GetThemeProviderForProfile(profile_.get()); |
| 429 SkColor frame_color = theme_provider.GetColor(ThemeProperties::COLOR_FRAME); |
| 430 SkColor theme_color = AlphaBlend( |
| 431 theme_provider.GetColor(ThemeProperties::COLOR_TOOLBAR_TOP_SEPARATOR), |
| 432 frame_color); |
| 433 SkColor tab_color = theme_provider.GetColor(ThemeProperties::COLOR_TOOLBAR); |
| 434 SkColor separator_color = GetSeparatorColor(tab_color, frame_color); |
| 435 EXPECT_EQ(theme_color, separator_color); |
| 436 |
| 437 // For the default theme, the separator should darken the frame. |
| 438 double frame_luminance = color_utils::GetRelativeLuminance(frame_color); |
| 439 EXPECT_LT(color_utils::GetRelativeLuminance(separator_color), |
| 440 frame_luminance); |
| 441 |
| 442 // If we reverse the colors, the separator should darken the "frame" (which |
| 443 // in this case is actually the tab color), since otherwise the contrast with |
| 444 // the "frame" would be too minimal. It should also be darker than the "tab" |
| 445 // (frame color) since otherwise the contrast the contrast with the "tab |
| 446 // color" would be too minimal. |
| 447 separator_color = GetSeparatorColor(frame_color, tab_color); |
| 448 double tab_luminance = color_utils::GetRelativeLuminance(tab_color); |
| 449 double separator_luminance = |
| 450 color_utils::GetRelativeLuminance(separator_color); |
| 451 EXPECT_LT(separator_luminance, tab_luminance); |
| 452 EXPECT_LT(separator_luminance, frame_luminance); |
| 453 |
| 454 // When the frame color is black, the separator should lighten the frame, but |
| 455 // it should still be darker than the tab color. |
| 456 separator_color = GetSeparatorColor(tab_color, SK_ColorBLACK); |
| 457 separator_luminance = color_utils::GetRelativeLuminance(separator_color); |
| 458 EXPECT_GT(separator_luminance, 0); |
| 459 EXPECT_LT(separator_luminance, tab_luminance); |
| 460 |
| 461 // When the frame color is white, the separator should darken the frame; it |
| 462 // should also be lighter than the tab color since otherwise the contrast with |
| 463 // the tab would be too minimal. |
| 464 separator_color = GetSeparatorColor(tab_color, SK_ColorWHITE); |
| 465 separator_luminance = color_utils::GetRelativeLuminance(separator_color); |
| 466 EXPECT_LT(separator_luminance, 1); |
| 467 EXPECT_LT(separator_luminance, tab_luminance); |
| 468 |
| 469 // Now make similar checks as above but for the incognito theme. |
| 470 const ui::ThemeProvider& otr_provider = |
| 471 ThemeService::GetThemeProviderForProfile( |
| 472 profile_->GetOffTheRecordProfile()); |
| 473 frame_color = otr_provider.GetColor(ThemeProperties::COLOR_FRAME); |
| 474 theme_color = AlphaBlend( |
| 475 otr_provider.GetColor(ThemeProperties::COLOR_TOOLBAR_TOP_SEPARATOR), |
| 476 frame_color); |
| 477 tab_color = otr_provider.GetColor(ThemeProperties::COLOR_TOOLBAR); |
| 478 separator_color = GetSeparatorColor(tab_color, frame_color); |
| 479 EXPECT_EQ(theme_color, separator_color); |
| 480 |
| 481 // For the default incognito theme, the separator should darken the frame. |
| 482 EXPECT_LT(color_utils::GetRelativeLuminance(separator_color), |
| 483 color_utils::GetRelativeLuminance(frame_color)); |
| 484 |
| 485 // And if we reverse the colors, the separator should lighten the "frame" |
| 486 // (tab color). |
| 487 separator_color = GetSeparatorColor(frame_color, tab_color); |
| 488 tab_luminance = color_utils::GetRelativeLuminance(tab_color); |
| 489 EXPECT_GT(color_utils::GetRelativeLuminance(separator_color), tab_luminance); |
| 490 |
| 491 // When the frame color is black, the separator should lighten the frame; it |
| 492 // should also be lighter than the tab color since otherwise the contrast with |
| 493 // the tab would be too minimal. |
| 494 separator_color = GetSeparatorColor(tab_color, SK_ColorBLACK); |
| 495 separator_luminance = color_utils::GetRelativeLuminance(separator_color); |
| 496 EXPECT_GT(separator_luminance, 0); |
| 497 EXPECT_GT(separator_luminance, tab_luminance); |
| 498 |
| 499 // When the frame color is white, the separator should darken the frame, but |
| 500 // it should still be lighter than the tab color. |
| 501 separator_color = GetSeparatorColor(tab_color, SK_ColorWHITE); |
| 502 separator_luminance = color_utils::GetRelativeLuminance(separator_color); |
| 503 EXPECT_LT(separator_luminance, 1); |
| 504 EXPECT_GT(separator_luminance, tab_luminance); |
| 505 } |
| 506 #endif // !defined(OS_MACOSX) |
| 507 |
| 379 }; // namespace theme_service_internal | 508 }; // namespace theme_service_internal |
| OLD | NEW |