chromium/chrome/browser/ui/views/frame/browser_frame_browsertest.cc

// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/views/frame/browser_frame.h"

#include "base/scoped_observation.h"
#include "base/test/bind.h"
#include "build/build_config.h"
#include "chrome/browser/devtools/devtools_window_testing.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/themes/theme_service.h"
#include "chrome/browser/themes/theme_service_factory.h"
#include "chrome/browser/themes/theme_syncable_service.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/views/chrome_views_delegate.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
#include "chrome/browser/web_applications/test/os_integration_test_override_impl.h"
#include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
#include "chrome/browser/web_applications/web_app_install_info.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/invalidate_type.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "ui/base/mojom/themes.mojom.h"
#include "ui/base/ui_base_features.h"
#include "ui/color/color_id.h"
#include "ui/color/color_mixer.h"
#include "ui/color/color_provider.h"
#include "ui/color/color_provider_key.h"
#include "ui/color/color_provider_manager.h"
#include "ui/color/color_recipe.h"
#include "ui/native_theme/test_native_theme.h"
#include "ui/views/bubble/bubble_dialog_model_host.h"
#include "ui/views/views_delegate.h"

namespace {

ui::mojom::BrowserColorVariant GetColorVariant(
    ui::ColorProviderKey::SchemeVariant scheme_variant) {}

}  // namespace

class BrowserFrameBoundsChecker : public ChromeViewsDelegate {};

class BrowserFrameTest : public InProcessBrowserTest {};

// Verifies that the tools are loaded with initial bounds.
IN_PROC_BROWSER_TEST_F(BrowserFrameTest, DevToolsHasBoundsOnOpen) {}

// Verifies that the web app is loaded with initial bounds.
IN_PROC_BROWSER_TEST_F(BrowserFrameTest, WebAppsHasBoundsOnOpen) {}

class MockThemeObserver : public views::WidgetObserver {};

// Verifies that theme change notifications are propagated to child widgets for
// browser theme changes.
IN_PROC_BROWSER_TEST_F(BrowserFrameTest, ChildWidgetsReceiveThemeUpdates) {}

// Regression test for crbug.com/1476462. Ensures that browser theme change
// notifications are always propagated correctly by the BrowserFrame with a
// default frame type.
IN_PROC_BROWSER_TEST_F(BrowserFrameTest,
                       ReceivesBrowserThemeUpdatesForDefaultFrames) {}

class BrowserFrameColorProviderTest : public BrowserFrameTest {};

// Verifies the BrowserFrame honors the BrowserColorScheme pref.
IN_PROC_BROWSER_TEST_F(BrowserFrameColorProviderTest,
                       TracksBrowserColorScheme) {}

// Verifies incognito browsers will always use the dark ColorMode.
IN_PROC_BROWSER_TEST_F(BrowserFrameColorProviderTest, IncognitoAlwaysDarkMode) {}

// Verifies the BrowserFrame's user_color tracks the autogenerated theme color.
IN_PROC_BROWSER_TEST_F(BrowserFrameColorProviderTest,
                       UserColorTracksAutogeneratedThemeColor) {}

// Verifies BrowserFrame tracks the profile kUserColor pref correctly.
IN_PROC_BROWSER_TEST_F(BrowserFrameColorProviderTest,
                       UserColorProfilePrefTrackedCorrectly) {}

// Verifies incognito browsers will ignore the user_color set on their
// NativeTheme and are configured to source colors from the grayscale palette.
IN_PROC_BROWSER_TEST_F(BrowserFrameColorProviderTest,
                       IncognitoAlwaysIgnoresUserColor) {}

// Verifies the BrowserFrame's user_color tracks the is_grayscale theme pref.
IN_PROC_BROWSER_TEST_F(BrowserFrameColorProviderTest,
                       BrowserFrameTracksIsGrayscale) {}

IN_PROC_BROWSER_TEST_F(BrowserFrameColorProviderTest,
                       GrayscaleIgnoresUserColor) {}

// Verifies incognito browsers always force the grayscale palette.
IN_PROC_BROWSER_TEST_F(BrowserFrameColorProviderTest,
                       IncognitoIsAlwaysGrayscale) {}

// Verifies the BrowserFrame's ColorProviderKey tracks the kBrowserColorVariant
// pref.
IN_PROC_BROWSER_TEST_F(BrowserFrameColorProviderTest,
                       BrowserFrameTracksBrowserColorVariant) {}

// Verifies the BrowserFrame's ColorProviderKey tracks the
// `NativeTheme::user_color` on ChromeOS and the color from `ThemeService` on
// platforms where the toggle is not available.
IN_PROC_BROWSER_TEST_F(BrowserFrameColorProviderTest, UseDeviceIgnoresTheme) {}

#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN)
// Verifies the BrowserFrame's ColorProviderKey tracks device even if
// AutogeneratedTheme is used.
IN_PROC_BROWSER_TEST_F(BrowserFrameColorProviderTest,
                       UseDeviceIgnoresAutogeneratedTheme) {
  constexpr SkColor kNativeThemeColor = SK_ColorMAGENTA;

  views::Widget* browser_frame = GetBrowserFrame(browser());
  ui::NativeTheme* native_theme = browser_frame->GetNativeTheme();
  native_theme->set_user_color(kNativeThemeColor);
  native_theme->set_scheme_variant(
      ui::ColorProviderKey::SchemeVariant::kVibrant);

  // Set `ThemeService` to use an autogenerated theme.
  auto* theme_service = GetThemeService(profile());
  constexpr SkColor kAutogeneratedColor1 = SkColorSetRGB(100, 100, 100);
  theme_service->BuildAutogeneratedThemeFromColor(kAutogeneratedColor1);
  ASSERT_EQ(kAutogeneratedColor1, theme_service->GetAutogeneratedThemeColor());
  EXPECT_EQ(ui::ColorProviderKey::UserColorSource::kAccent,
            GetColorProviderKey(browser()).user_color_source);

  // Prefer color from NativeTheme.
  SetFollowDevice(profile(), true);

  // Device theme is preferred over autogenerated if device theme is true.
  EXPECT_EQ(kNativeThemeColor, GetColorProviderKey(browser()).user_color);
  EXPECT_EQ(ui::ColorProviderKey::UserColorSource::kAccent,
            GetColorProviderKey(browser()).user_color_source);
}

// Verify that that grayscale is ignored if UseDeviceTheme is true.
IN_PROC_BROWSER_TEST_F(BrowserFrameColorProviderTest,
                       UseDeviceThemeIgnoresGrayscale) {
  views::Widget* browser_frame = GetBrowserFrame(browser());
  // Set native theme to an obviously different color.
  ui::NativeTheme* native_theme = browser_frame->GetNativeTheme();
  native_theme->set_user_color(SK_ColorMAGENTA);
  native_theme->set_scheme_variant(
      ui::ColorProviderKey::SchemeVariant::kVibrant);

  SetIsGrayscale(profile(), true);
  // Prefer color from NativeTheme.
  SetFollowDevice(profile(), true);

  EXPECT_EQ(SK_ColorMAGENTA, GetColorProviderKey(browser()).user_color);
  EXPECT_EQ(ui::ColorProviderKey::UserColorSource::kAccent,
            GetColorProviderKey(browser()).user_color_source);
}
#endif

IN_PROC_BROWSER_TEST_F(BrowserFrameColorProviderTest,
                       BaselineThemeIgnoresNativeThemeColor) {}