blob: 73ad83d3735299fd589bc4b5c635dbb86ec615a4 [file] [log] [blame]
// 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 "chrome/browser/ui/views/sharing/sharing_icon_view.h"
#include "base/memory/raw_ptr.h"
#include "chrome/app/vector_icons/vector_icons.h"
#include "chrome/browser/command_updater_impl.h"
#include "chrome/browser/sharing/click_to_call/click_to_call_ui_controller.h"
#include "chrome/browser/sharing/sharing_ui_controller.h"
#include "chrome/browser/sharing/sms/sms_remote_fetcher_ui_controller.h"
#include "chrome/browser/ui/views/sharing/sharing_dialog_view.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/views/chrome_views_test_base.h"
#include "content/public/test/test_renderer_host.h"
#include "content/public/test/web_contents_tester.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/events/test/event_generator.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/gfx/vector_icon_types.h"
#include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/widget/widget_utils.h"
constexpr int kPageActionIconSize = 20;
class TestPageActionIconDelegate : public IconLabelBubbleView::Delegate,
public PageActionIconView::Delegate {
public:
explicit TestPageActionIconDelegate(
raw_ptr<content::WebContents> web_contents)
: web_contents_(web_contents) {}
TestPageActionIconDelegate() = default;
virtual ~TestPageActionIconDelegate() = default;
// IconLabelBubbleView::Delegate:
SkColor GetIconLabelBubbleSurroundingForegroundColor() const override {
return gfx::kPlaceholderColor;
}
SkColor GetIconLabelBubbleBackgroundColor() const override {
return gfx::kPlaceholderColor;
}
// PageActionIconView::Delegate:
content::WebContents* GetWebContentsForPageActionIconView() override {
return web_contents_;
}
int GetPageActionIconSize() const override { return kPageActionIconSize; }
bool ShouldHidePageActionIcons() const override {
return should_hide_page_action_icons_;
}
void set_should_hide_page_action_icons(bool should_hide_page_action_icons) {
should_hide_page_action_icons_ = should_hide_page_action_icons;
}
void ClearWebContents() { web_contents_ = nullptr; }
private:
bool should_hide_page_action_icons_ = false;
raw_ptr<content::WebContents> web_contents_ = nullptr;
};
class TestSharingIconView : public SharingIconView {
public:
using SharingIconView::AnimateIn;
explicit TestSharingIconView(IconLabelBubbleView::Delegate* parent_delegate,
PageActionIconView::Delegate* delegate,
GetControllerCallback get_controller_callback,
GetBubbleCallback get_bubble_callback)
: SharingIconView(parent_delegate,
delegate,
get_controller_callback,
get_bubble_callback) {
SetUpForInOutAnimation();
}
views::BubbleDialogDelegate* GetBubble() const override { return nullptr; }
bool IsLabelVisible() const { return label()->GetVisible(); }
protected:
// PageActionIconView:
void OnExecuting(ExecuteSource execute_source) override {}
const gfx::VectorIcon& GetVectorIcon() const override {
return gfx::VectorIcon::EmptyIcon();
}
void UpdateImpl() override {}
};
class SharingIconViewTest : public ChromeViewsTestBase {
protected:
// ChromeViewsTestBase:
void SetUp() override {
ChromeViewsTestBase::SetUp();
widget_ = CreateTestWidget(views::Widget::InitParams::CLIENT_OWNS_WIDGET);
test_web_contents_ =
content::WebContentsTester::CreateTestWebContents(&profile_, nullptr);
test_web_contents_->Resize(
gfx::Rect(/*x=*/0, /*y=*/0, /*width=*/1000, /*height=*/1000));
delegate_ = TestPageActionIconDelegate(test_web_contents_.get());
view_ = widget_->SetContentsView(std::make_unique<TestSharingIconView>(
delegate(), delegate(),
base::BindRepeating([](content::WebContents* contents) {
return static_cast<SharingUiController*>(
ClickToCallUiController::GetOrCreateFromWebContents(contents));
}),
base::BindRepeating(SharingDialogView::GetAsBubbleForClickToCall)));
widget_->Show();
}
void TearDown() override {
ClearView();
widget_.reset();
delegate_.ClearWebContents();
ChromeViewsTestBase::TearDown();
}
void ClearView() { view_ = nullptr; }
void InitialiseViewWithInaccessibleUi() {
ClearView();
view_ = widget_->SetContentsView(std::make_unique<TestSharingIconView>(
delegate(), delegate(),
base::BindRepeating([](content::WebContents* contents) {
return static_cast<SharingUiController*>(
SmsRemoteFetcherUiController::GetOrCreateFromWebContents(
contents));
}),
base::BindRepeating(SharingDialogView::GetAsBubbleForClickToCall)));
}
TestSharingIconView* view() { return view_; }
views::Widget* widget() { return widget_.get(); }
TestPageActionIconDelegate* delegate() { return &delegate_; }
private:
TestPageActionIconDelegate delegate_;
raw_ptr<TestSharingIconView> view_ = nullptr;
std::unique_ptr<views::Widget> widget_;
// This enables uses of TestWebContents.
content::RenderViewHostTestEnabler test_render_host_factories_;
TestingProfile profile_;
std::unique_ptr<content::WebContents> test_web_contents_;
};
TEST_F(SharingIconViewTest, IgnoredAccessibleState) {
ui::AXNodeData node_data;
view()->GetViewAccessibility().GetAccessibleNodeData(&node_data);
EXPECT_FALSE(node_data.HasState(ax::mojom::State::kIgnored));
InitialiseViewWithInaccessibleUi();
node_data = ui::AXNodeData();
view()->GetViewAccessibility().GetAccessibleNodeData(&node_data);
EXPECT_TRUE(node_data.HasState(ax::mojom::State::kIgnored));
}