blob: de23bf33697f84d33041f88890286631ff273a11 [file]
// 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 UI_VIEWS_TEST_MOCK_ACTIVATION_CONTROLLER_H_
#define UI_VIEWS_TEST_MOCK_ACTIVATION_CONTROLLER_H_
#include <string>
#include <vector>
#include "base/functional/callback.h"
#include "base/memory/weak_ptr.h"
#include "ui/views/buildflags.h"
#include "ui/views/widget/widget_activation_delegate.h"
#include "ui/views/widget/widget_observer.h"
// Only desktop aura platforms or macOS needs the activation emulation.
#if BUILDFLAG(ENABLE_DESKTOP_AURA) || BUILDFLAG(IS_MAC)
#define USE_MOCK_ACTIVATION_CONTROLLER 1
namespace views {
class Widget;
namespace test {
// MockActivationController class provides platform-independent widget
// activation by emulating the window stacking, activation, and deactivation.
//
// Normally, the underlying platform/OS handles activation/deactivation, but
// relying on such an environment prevents us from running multiple tests in
// parallel because there is only one active window at a time, and activating a
// window in one test may deactivate a window in another test. This class allows
// such tests to run in parallel.
//
// Caveats:
// 1) Do not use this class directly in test code. Just instantiating this class
// should enable the emulation.
// 2) This can only handle a window created by views::Widget. If you create a
// native window (e.g. aura::Window) without the views framework, it will not be
// emulated. Such a case should not exist, as a window that should be activated
// should have UI elements.
// 3) Mac does not support Widget::Deactivate, but deactivation can still
// happen by hiding a Widget. This class emulates this scenario as well.
class MockActivationController : public views::WidgetObserver,
public WidgetActivationDelegate {
public:
MockActivationController();
MockActivationController(const MockActivationController&) = delete;
MockActivationController operator=(const MockActivationController&) = delete;
~MockActivationController() override;
void MaybeActivate(Widget* widget, bool activate) override;
void Deactivate(Widget* widget) override;
bool IsActive(const Widget* widget) override;
private:
// WidgetObserver:
void OnWidgetDestroying(Widget* widget) override;
void OnWidgetVisibilityChanged(Widget* widget, bool visible) override;
using WidgetList = std::vector<raw_ptr<Widget, VectorExperimental>>;
WidgetList::reverse_iterator FindActivatableWidget();
WidgetList widgets_;
raw_ptr<Widget> active_widget_ = nullptr;
};
} // namespace test
} // namespace views
#endif // BUILDFLAG(ENABLE_DESKTOP_AURA) || BUILDFLAG(IS_MAC)
#endif // UI_VIEWS_TEST_MOCK_ACTIVATION_CONTROLLER_H_