1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/views/frame/opaque_browser_frame_view.h"
6
7 #include "build/build_config.h"
8 #include "chrome/browser/themes/theme_service.h"
9 #include "chrome/browser/themes/theme_service_factory.h"
10 #include "chrome/browser/ui/browser.h"
11 #include "chrome/browser/ui/views/frame/browser_view.h"
12 #include "chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.h"
13 #include "chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.h"
14 #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
15 #include "chrome/browser/web_applications/components/web_application_info.h"
16 #include "chrome/test/base/in_process_browser_test.h"
17 #include "content/public/test/browser_test.h"
18 #include "ui/gfx/color_utils.h"
19 #include "ui/views/test/test_views.h"
20
21 // Tests web-app windows that use the OpaqueBrowserFrameView implementation
22 // for their non client frames.
23 class WebAppOpaqueBrowserFrameViewTest : public InProcessBrowserTest {
24 public:
25 WebAppOpaqueBrowserFrameViewTest() = default;
26 ~WebAppOpaqueBrowserFrameViewTest() override = default;
27
GetAppURL()28 static GURL GetAppURL() { return GURL("https://test.org"); }
29
SetUpOnMainThread()30 void SetUpOnMainThread() override { SetThemeMode(ThemeMode::kDefault); }
31
InstallAndLaunchWebApp(base::Optional<SkColor> theme_color=base::nullopt)32 bool InstallAndLaunchWebApp(
33 base::Optional<SkColor> theme_color = base::nullopt) {
34 auto web_app_info = std::make_unique<WebApplicationInfo>();
35 web_app_info->start_url = GetAppURL();
36 web_app_info->scope = GetAppURL().GetWithoutFilename();
37 web_app_info->theme_color = theme_color;
38
39 web_app::AppId app_id =
40 web_app::InstallWebApp(browser()->profile(), std::move(web_app_info));
41 Browser* app_browser =
42 web_app::LaunchWebAppBrowser(browser()->profile(), app_id);
43
44 views::NonClientFrameView* frame_view =
45 BrowserView::GetBrowserViewForBrowser(app_browser)
46 ->GetWidget()
47 ->non_client_view()
48 ->frame_view();
49
50 // Not all platform configurations use OpaqueBrowserFrameView for their
51 // browser windows, see |CreateBrowserNonClientFrameView()|.
52 bool is_opaque_browser_frame_view =
53 frame_view->GetClassName() == OpaqueBrowserFrameView::kClassName;
54 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
55 DCHECK(is_opaque_browser_frame_view);
56 #else
57 if (!is_opaque_browser_frame_view)
58 return false;
59 #endif
60
61 opaque_browser_frame_view_ =
62 static_cast<OpaqueBrowserFrameView*>(frame_view);
63 web_app_frame_toolbar_ =
64 opaque_browser_frame_view_->web_app_frame_toolbar_for_testing();
65 DCHECK(web_app_frame_toolbar_);
66 DCHECK(web_app_frame_toolbar_->GetVisible());
67
68 return true;
69 }
70
GetRestoredTitleBarHeight()71 int GetRestoredTitleBarHeight() {
72 return opaque_browser_frame_view_->layout()->NonClientTopHeight(true);
73 }
74
75 enum class ThemeMode {
76 kSystem,
77 kDefault,
78 };
79
SetThemeMode(ThemeMode theme_mode)80 void SetThemeMode(ThemeMode theme_mode) {
81 ThemeService* theme_service =
82 ThemeServiceFactory::GetForProfile(browser()->profile());
83 if (theme_mode == ThemeMode::kSystem)
84 theme_service->UseSystemTheme();
85 else
86 theme_service->UseDefaultTheme();
87 ASSERT_EQ(theme_service->UsingDefaultTheme(),
88 theme_mode == ThemeMode::kDefault);
89 }
90
91 OpaqueBrowserFrameView* opaque_browser_frame_view_ = nullptr;
92 WebAppFrameToolbarView* web_app_frame_toolbar_ = nullptr;
93
94 private:
95 DISALLOW_COPY_AND_ASSIGN(WebAppOpaqueBrowserFrameViewTest);
96 };
97
IN_PROC_BROWSER_TEST_F(WebAppOpaqueBrowserFrameViewTest,NoThemeColor)98 IN_PROC_BROWSER_TEST_F(WebAppOpaqueBrowserFrameViewTest, NoThemeColor) {
99 if (!InstallAndLaunchWebApp())
100 return;
101 EXPECT_EQ(web_app_frame_toolbar_->active_color_for_testing(),
102 gfx::kGoogleGrey900);
103 }
104
105 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
106 // The app theme color should be ignored in system theme mode.
IN_PROC_BROWSER_TEST_F(WebAppOpaqueBrowserFrameViewTest,SystemThemeColor)107 IN_PROC_BROWSER_TEST_F(WebAppOpaqueBrowserFrameViewTest, SystemThemeColor) {
108 SetThemeMode(ThemeMode::kSystem);
109
110 // Read unthemed native frame color.
111 SkColor native_frame_color =
112 BrowserView::GetBrowserViewForBrowser(browser())
113 ->frame()
114 ->GetFrameView()
115 ->GetFrameColor(BrowserFrameActiveState::kActive);
116 SkColor expected_caption_color =
117 color_utils::GetColorWithMaxContrast(native_frame_color);
118
119 // Install web app with theme color contrasting against native frame color.
120 SkColor theme_color =
121 color_utils::GetColorWithMaxContrast(native_frame_color);
122 EXPECT_NE(color_utils::IsDark(theme_color),
123 color_utils::IsDark(native_frame_color));
124 ASSERT_TRUE(InstallAndLaunchWebApp(theme_color));
125
126 // App theme color should be ignored in favor of native system theme.
127 EXPECT_EQ(opaque_browser_frame_view_->GetFrameColor(
128 BrowserFrameActiveState::kActive),
129 native_frame_color);
130 EXPECT_EQ(opaque_browser_frame_view_->GetCaptionColor(
131 BrowserFrameActiveState::kActive),
132 expected_caption_color);
133 EXPECT_EQ(web_app_frame_toolbar_->active_color_for_testing(),
134 expected_caption_color);
135 }
136 #endif // defined(OS_LINUX) && !defined(OS_CHROMEOS)
137
IN_PROC_BROWSER_TEST_F(WebAppOpaqueBrowserFrameViewTest,LightThemeColor)138 IN_PROC_BROWSER_TEST_F(WebAppOpaqueBrowserFrameViewTest, LightThemeColor) {
139 if (!InstallAndLaunchWebApp(SK_ColorYELLOW))
140 return;
141 EXPECT_EQ(web_app_frame_toolbar_->active_color_for_testing(),
142 gfx::kGoogleGrey900);
143 }
144
IN_PROC_BROWSER_TEST_F(WebAppOpaqueBrowserFrameViewTest,DarkThemeColor)145 IN_PROC_BROWSER_TEST_F(WebAppOpaqueBrowserFrameViewTest, DarkThemeColor) {
146 if (!InstallAndLaunchWebApp(SK_ColorBLUE))
147 return;
148 EXPECT_EQ(web_app_frame_toolbar_->active_color_for_testing(), SK_ColorWHITE);
149 }
150
IN_PROC_BROWSER_TEST_F(WebAppOpaqueBrowserFrameViewTest,MediumThemeColor)151 IN_PROC_BROWSER_TEST_F(WebAppOpaqueBrowserFrameViewTest, MediumThemeColor) {
152 // Use the theme color for Gmail.
153 if (!InstallAndLaunchWebApp(SkColorSetRGB(0xd6, 0x49, 0x3b)))
154 return;
155 EXPECT_EQ(web_app_frame_toolbar_->active_color_for_testing(), SK_ColorWHITE);
156 }
157
IN_PROC_BROWSER_TEST_F(WebAppOpaqueBrowserFrameViewTest,StaticTitleBarHeight)158 IN_PROC_BROWSER_TEST_F(WebAppOpaqueBrowserFrameViewTest, StaticTitleBarHeight) {
159 if (!InstallAndLaunchWebApp())
160 return;
161
162 opaque_browser_frame_view_->Layout();
163 const int title_bar_height = GetRestoredTitleBarHeight();
164 EXPECT_GT(title_bar_height, 0);
165
166 // Add taller children to the web app frame toolbar RHS.
167 const int container_height = web_app_frame_toolbar_->height();
168 web_app_frame_toolbar_->GetRightContainerForTesting()->AddChildView(
169 new views::StaticSizedView(gfx::Size(1, title_bar_height * 2)));
170 opaque_browser_frame_view_->Layout();
171
172 // The height of the web app frame toolbar and title bar should not be
173 // affected.
174 EXPECT_EQ(container_height, web_app_frame_toolbar_->height());
175 EXPECT_EQ(title_bar_height, GetRestoredTitleBarHeight());
176 }
177