diff --git a/chrome/browser/ui/browser_window/test/fake_browser_window_eval.cc b/chrome/browser/ui/browser_window/test/fake_browser_window_eval.cc new file mode 100644 index 0000000000000..afa110ec34bb1 --- /dev/null +++ b/chrome/browser/ui/browser_window/test/fake_browser_window_eval.cc @@ -0,0 +1,22 @@ +// Copyright 2026 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/browser_window/test/fake_browser_window_eval.h" + +#include + +namespace fake_bwf_eval { + +FakeBrowserWindow::FakeBrowserWindow() = default; +FakeBrowserWindow::~FakeBrowserWindow() = default; + +void FakeBrowserWindow::ShowQRCodeBubble() { + last_message_ = "QR bubble shown by BrowserWindow"; +} + +void FakeBrowserWindow::SetLastMessageForTesting(std::string message) { + last_message_ = std::move(message); +} + +} // namespace fake_bwf_eval diff --git a/chrome/browser/ui/browser_window/test/fake_browser_window_eval.h b/chrome/browser/ui/browser_window/test/fake_browser_window_eval.h new file mode 100644 index 0000000000000..92266b25f671f --- /dev/null +++ b/chrome/browser/ui/browser_window/test/fake_browser_window_eval.h @@ -0,0 +1,28 @@ +// Copyright 2026 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_BROWSER_WINDOW_TEST_FAKE_BROWSER_WINDOW_EVAL_H_ +#define CHROME_BROWSER_UI_BROWSER_WINDOW_TEST_FAKE_BROWSER_WINDOW_EVAL_H_ + +#include + +namespace fake_bwf_eval { + +class FakeBrowserWindow { + public: + FakeBrowserWindow(); + ~FakeBrowserWindow(); + + void ShowQRCodeBubble(); + + void SetLastMessageForTesting(std::string message); + const std::string& last_message_for_testing() const { return last_message_; } + + private: + std::string last_message_; +}; + +} // namespace fake_bwf_eval + +#endif // CHROME_BROWSER_UI_BROWSER_WINDOW_TEST_FAKE_BROWSER_WINDOW_EVAL_H_ diff --git a/chrome/browser/ui/browser_window/test/fake_browser_window_features_eval.cc b/chrome/browser/ui/browser_window/test/fake_browser_window_features_eval.cc new file mode 100644 index 0000000000000..7227666ad2567 --- /dev/null +++ b/chrome/browser/ui/browser_window/test/fake_browser_window_features_eval.cc @@ -0,0 +1,121 @@ +// Copyright 2026 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/browser_window/test/fake_browser_window_features_eval.h" + +#include "base/no_destructor.h" + +namespace fake_bwf_eval { + +FakeBrowserWindowInterface::FakeBrowserWindowInterface(Type type) + : type_(type) {} +FakeBrowserWindowInterface::~FakeBrowserWindowInterface() = default; + +bool FakeBrowserWindowInterface::is_type_normal() const { + return type_ == Type::kNormal; +} + +DEFINE_USER_DATA(FakeBookmarkController); +FakeBookmarkController::FakeBookmarkController( + FakeBrowserWindowInterface* browser) + : scoped_user_data_(browser->GetUnownedUserDataHost(), *this) {} +FakeBookmarkController::~FakeBookmarkController() = default; +// static +FakeBookmarkController* FakeBookmarkController::From( + FakeBrowserWindowInterface* browser) { + return browser ? Get(browser->GetUnownedUserDataHost()) : nullptr; +} + +DEFINE_USER_DATA(FakeEmbedderFeatures); +FakeEmbedderFeatures::FakeEmbedderFeatures(FakeBrowserWindowInterface* browser) + : scoped_user_data_(browser->GetUnownedUserDataHost(), *this) {} +FakeEmbedderFeatures::~FakeEmbedderFeatures() = default; +// static +FakeEmbedderFeatures* FakeEmbedderFeatures::From( + FakeBrowserWindowInterface* browser) { + return browser ? Get(browser->GetUnownedUserDataHost()) : nullptr; +} + +DEFINE_USER_DATA(FakeProfileMenuController); +FakeProfileMenuController::FakeProfileMenuController( + FakeBrowserWindowInterface* browser) + : scoped_user_data_(browser->GetUnownedUserDataHost(), *this) {} +FakeProfileMenuController::~FakeProfileMenuController() = default; +// static +FakeProfileMenuController* FakeProfileMenuController::From( + FakeBrowserWindowInterface* browser) { + return browser ? Get(browser->GetUnownedUserDataHost()) : nullptr; +} + +DEFINE_USER_DATA(FakeSendTabController); +FakeSendTabController::FakeSendTabController( + FakeBrowserWindowInterface* browser) + : scoped_user_data_(browser->GetUnownedUserDataHost(), *this) {} +FakeSendTabController::~FakeSendTabController() = default; +// static +FakeSendTabController* FakeSendTabController::From( + FakeBrowserWindowInterface* browser) { + return browser ? Get(browser->GetUnownedUserDataHost()) : nullptr; +} + +DEFINE_USER_DATA(FakeSidePanelRegistry); +FakeSidePanelRegistry::FakeSidePanelRegistry( + FakeBrowserWindowInterface* browser) + : scoped_user_data_(browser->GetUnownedUserDataHost(), *this) {} +FakeSidePanelRegistry::~FakeSidePanelRegistry() = default; +// static +FakeSidePanelRegistry* FakeSidePanelRegistry::From( + FakeBrowserWindowInterface* browser) { + return browser ? Get(browser->GetUnownedUserDataHost()) : nullptr; +} + +FakeBrowserWindowFeatures::FakeBrowserWindowFeatures() = default; +FakeBrowserWindowFeatures::~FakeBrowserWindowFeatures() = default; + +void FakeBrowserWindowFeatures::Init(FakeBrowserWindowInterface* browser) { + browser_ = browser; + + // Members owned by all browser window types. + fake_bookmark_controller_ = + GetUserDataFactory().CreateInstance(*browser, + browser); + fake_side_panel_registry_ = + GetUserDataFactory().CreateInstance(*browser, + browser); + + // Embedder features are initialized last. + fake_embedder_features_ = + GetUserDataFactory().CreateInstance(*browser, + browser); +} + +void FakeBrowserWindowFeatures::InitPostWindowConstruction( + FakeBrowserWindowInterface* browser, + FakeBrowserWindow* window) { + // Members owned by all browser window types. + fake_profile_menu_controller_ = + GetUserDataFactory().CreateInstance(*browser, + browser); + + // Members owned only when the browser is TYPE_NORMAL. + if (browser->is_type_normal()) { + fake_send_tab_controller_ = + GetUserDataFactory().CreateInstance(*browser, + browser); + window->ShowQRCodeBubble(); + } +} + +void FakeBrowserWindowFeatures::InitPostBrowserViewConstruction() {} + +// static +ui::UserDataFactoryWithOwner& +FakeBrowserWindowFeatures::GetUserDataFactory() { + static base::NoDestructor< + ui::UserDataFactoryWithOwner> + factory; + return *factory; +} + +} // namespace fake_bwf_eval diff --git a/chrome/browser/ui/browser_window/test/fake_browser_window_features_eval.h b/chrome/browser/ui/browser_window/test/fake_browser_window_features_eval.h new file mode 100644 index 0000000000000..fd6343a1c57e3 --- /dev/null +++ b/chrome/browser/ui/browser_window/test/fake_browser_window_features_eval.h @@ -0,0 +1,165 @@ +// Copyright 2026 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_BROWSER_WINDOW_TEST_FAKE_BROWSER_WINDOW_FEATURES_EVAL_H_ +#define CHROME_BROWSER_UI_BROWSER_WINDOW_TEST_FAKE_BROWSER_WINDOW_FEATURES_EVAL_H_ + +#include + +#include "base/memory/raw_ptr.h" +#include "chrome/browser/ui/browser_window/test/fake_browser_window_eval.h" +#include "ui/base/unowned_user_data/scoped_unowned_user_data.h" +#include "ui/base/unowned_user_data/unowned_user_data_host.h" +#include "ui/base/unowned_user_data/user_data_factory.h" + +namespace fake_bwf_eval { + +class FakeBookmarkController; +class FakeEmbedderFeatures; +class FakeProfileMenuController; +class FakeSendTabController; +class FakeSidePanelRegistry; + +class FakeBrowserWindowInterface { + public: + enum class Type { + kNormal, + kPopup, + }; + + explicit FakeBrowserWindowInterface(Type type); + ~FakeBrowserWindowInterface(); + + bool is_type_normal() const; + + ui::UnownedUserDataHost& GetUnownedUserDataHost() { + return unowned_user_data_host_; + } + + private: + Type type_; + ui::UnownedUserDataHost unowned_user_data_host_; +}; + +// Feature controllers register themselves as unowned user data and are reached +// through the static `From()` accessor. Construct them with +// `GetUserDataFactory().CreateInstance<>()` rather than `std::make_unique<>()`. +class FakeBookmarkController { + public: + DECLARE_USER_DATA(FakeBookmarkController); + + explicit FakeBookmarkController(FakeBrowserWindowInterface* browser); + FakeBookmarkController(const FakeBookmarkController&) = delete; + FakeBookmarkController& operator=(const FakeBookmarkController&) = delete; + ~FakeBookmarkController(); + + static FakeBookmarkController* From(FakeBrowserWindowInterface* browser); + + private: + ui::ScopedUnownedUserData scoped_user_data_; +}; + +class FakeEmbedderFeatures { + public: + DECLARE_USER_DATA(FakeEmbedderFeatures); + + explicit FakeEmbedderFeatures(FakeBrowserWindowInterface* browser); + FakeEmbedderFeatures(const FakeEmbedderFeatures&) = delete; + FakeEmbedderFeatures& operator=(const FakeEmbedderFeatures&) = delete; + ~FakeEmbedderFeatures(); + + static FakeEmbedderFeatures* From(FakeBrowserWindowInterface* browser); + + private: + ui::ScopedUnownedUserData scoped_user_data_; +}; + +class FakeProfileMenuController { + public: + DECLARE_USER_DATA(FakeProfileMenuController); + + explicit FakeProfileMenuController(FakeBrowserWindowInterface* browser); + FakeProfileMenuController(const FakeProfileMenuController&) = delete; + FakeProfileMenuController& operator=(const FakeProfileMenuController&) = + delete; + ~FakeProfileMenuController(); + + static FakeProfileMenuController* From(FakeBrowserWindowInterface* browser); + + private: + ui::ScopedUnownedUserData scoped_user_data_; +}; + +class FakeSendTabController { + public: + DECLARE_USER_DATA(FakeSendTabController); + + explicit FakeSendTabController(FakeBrowserWindowInterface* browser); + FakeSendTabController(const FakeSendTabController&) = delete; + FakeSendTabController& operator=(const FakeSendTabController&) = delete; + ~FakeSendTabController(); + + static FakeSendTabController* From(FakeBrowserWindowInterface* browser); + + private: + ui::ScopedUnownedUserData scoped_user_data_; +}; + +class FakeSidePanelRegistry { + public: + DECLARE_USER_DATA(FakeSidePanelRegistry); + + explicit FakeSidePanelRegistry(FakeBrowserWindowInterface* browser); + FakeSidePanelRegistry(const FakeSidePanelRegistry&) = delete; + FakeSidePanelRegistry& operator=(const FakeSidePanelRegistry&) = delete; + ~FakeSidePanelRegistry(); + + static FakeSidePanelRegistry* From(FakeBrowserWindowInterface* browser); + + private: + ui::ScopedUnownedUserData scoped_user_data_; +}; + +// Do not add public accessors for feature controllers. Reach them through the +// UnownedUserData access pattern (`FooController::From(browser)`) instead of +// adding a getter here. +class FakeBrowserWindowFeatures { + public: + FakeBrowserWindowFeatures(); + ~FakeBrowserWindowFeatures(); + + FakeBrowserWindowFeatures(const FakeBrowserWindowFeatures&) = delete; + FakeBrowserWindowFeatures& operator=(const FakeBrowserWindowFeatures&) = + delete; + + void Init(FakeBrowserWindowInterface* browser); + void InitPostWindowConstruction(FakeBrowserWindowInterface* browser, + FakeBrowserWindow* window); + // Deprecated and intentionally empty: retained only to mirror the real + // BrowserWindowFeatures lifecycle. Do not add new feature initialization + // here; prefer InitPostWindowConstruction(). + void InitPostBrowserViewConstruction(); + + private: + static ui::UserDataFactoryWithOwner& + GetUserDataFactory(); + + // Members owned by all browser window types. + std::unique_ptr fake_bookmark_controller_; + std::unique_ptr fake_profile_menu_controller_; + std::unique_ptr fake_side_panel_registry_; + + // Members owned only when the browser is TYPE_NORMAL. + std::unique_ptr fake_send_tab_controller_; + + // Non-owning references. + raw_ptr browser_ = nullptr; + + // Embedder features. Must be declared last. + std::unique_ptr fake_embedder_features_; +}; + +} // namespace fake_bwf_eval + +#endif // CHROME_BROWSER_UI_BROWSER_WINDOW_TEST_FAKE_BROWSER_WINDOW_FEATURES_EVAL_H_