910e62b5创建于 1月15日历史提交
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/views/interaction/widget_focus_observer.h"

#include <memory>
#include <utility>

#include "base/functional/callback_helpers.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/interaction/framework_specific_implementation.h"
#include "ui/views/bubble/bubble_border.h"
#include "ui/views/bubble/bubble_dialog_delegate_view.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/test/widget_activation_waiter.h"
#include "ui/views/test/widget_test.h"
#include "ui/views/widget/widget.h"

namespace views {

namespace {

// Dummy supplier that doesn't do anything.
class DummyWidgetFocusSupplier : public test::internal::WidgetFocusSupplier {
 public:
  DummyWidgetFocusSupplier() = default;
  ~DummyWidgetFocusSupplier() override = default;

  DECLARE_FRAMEWORK_SPECIFIC_METADATA()

 protected:
  Widget::Widgets GetAllWidgets() const override {
    return test::WidgetTest::GetAllWidgets();
  }
};

DEFINE_FRAMEWORK_SPECIFIC_METADATA(DummyWidgetFocusSupplier)

}  // namespace

class WidgetFocusObserverTest : public ViewsTestBase {
 public:
  WidgetFocusObserverTest() {
    frame_.supplier_list().MaybeRegister<DummyWidgetFocusSupplier>();
  }
  ~WidgetFocusObserverTest() override = default;

 private:
  test::internal::WidgetFocusSupplierFrame frame_;
};

TEST_F(WidgetFocusObserverTest, NoWidgets) {
  test::WidgetFocusObserver observer;
  observer.SetStateObserverStateChangedCallback(base::DoNothing());
  EXPECT_EQ(nullptr, observer.GetStateObserverInitialState());
}

TEST_F(WidgetFocusObserverTest, OneWidget) {
  const auto widget = CreateTestWidget(Widget::InitParams::CLIENT_OWNS_WIDGET);
  test::WidgetVisibleWaiter visible_waiter(widget.get());
  widget->Show();
  visible_waiter.Wait();

  test::WidgetFocusObserver observer;
  observer.SetStateObserverStateChangedCallback(base::DoNothing());
  EXPECT_EQ(widget.get(), observer.GetStateObserverInitialState());
}

TEST_F(WidgetFocusObserverTest, SeveralWidgets) {
  const auto widget1 = CreateTestWidget(Widget::InitParams::CLIENT_OWNS_WIDGET);
  test::WidgetVisibleWaiter visible_waiter1(widget1.get());
  widget1->Show();
  visible_waiter1.Wait();

  const auto widget2 = CreateTestWidget(Widget::InitParams::CLIENT_OWNS_WIDGET);
  test::WidgetVisibleWaiter visible_waiter2(widget1.get());
  widget2->Show();
  visible_waiter2.Wait();

  const auto widget3 = CreateTestWidget(Widget::InitParams::CLIENT_OWNS_WIDGET);
  test::WidgetVisibleWaiter visible_waiter3(widget1.get());
  widget3->ShowInactive();
  visible_waiter3.Wait();

  test::WidgetFocusObserver observer;
  observer.SetStateObserverStateChangedCallback(base::DoNothing());
  EXPECT_EQ(widget2.get(), observer.GetStateObserverInitialState());
}

TEST_F(WidgetFocusObserverTest, AfterActivate) {
  const auto widget1 = CreateTestWidget(Widget::InitParams::CLIENT_OWNS_WIDGET);
  test::WidgetVisibleWaiter visible_waiter1(widget1.get());
  widget1->Show();
  visible_waiter1.Wait();

  const auto widget2 = CreateTestWidget(Widget::InitParams::CLIENT_OWNS_WIDGET);
  test::WidgetVisibleWaiter visible_waiter2(widget1.get());
  widget2->Show();
  visible_waiter2.Wait();

  const auto widget3 = CreateTestWidget(Widget::InitParams::CLIENT_OWNS_WIDGET);
  test::WidgetVisibleWaiter visible_waiter3(widget1.get());
  widget3->ShowInactive();
  visible_waiter3.Wait();

  widget3->Activate();
  test::WaitForWidgetActive(widget3.get(), true);

  test::WidgetFocusObserver observer;
  observer.SetStateObserverStateChangedCallback(base::DoNothing());
  EXPECT_EQ(widget3.get(), observer.GetStateObserverInitialState());
}

TEST_F(WidgetFocusObserverTest, Bubble) {
  const auto widget = CreateTestWidget(Widget::InitParams::CLIENT_OWNS_WIDGET);
  test::WidgetVisibleWaiter visible_waiter(widget.get());
  widget->Show();
  visible_waiter.Wait();

  auto bubble = std::make_unique<BubbleDialogDelegateView>(
      BubbleDialogDelegateView::CreatePassKey(), widget->GetRootView(),
      BubbleBorder::LEFT_CENTER);
  auto* const bubble_widget =
      BubbleDialogDelegate::CreateBubble(std::move(bubble));
  test::WidgetVisibleWaiter visible_waiter2(bubble_widget);
  bubble_widget->Show();
  visible_waiter2.Wait();

  test::WidgetFocusObserver observer;
  observer.SetStateObserverStateChangedCallback(base::DoNothing());
  EXPECT_EQ(bubble_widget,
            observer.GetStateObserverInitialState());
}

}  // namespace views