blob: 3bc9278a2d47f5ec0cb854df0c82043a351bf0b7 [file] [log] [blame]
// Copyright 2021 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/ash/arc/accessibility/arc_serialization_delegate.h"
#include <memory>
#include "base/memory/raw_ptr.h"
#include "chrome/browser/ash/arc/accessibility/arc_serialization_delegate.h"
#include "chrome/test/base/chrome_ash_test_base.h"
#include "components/exo/client_controlled_shell_surface.h"
#include "components/exo/surface.h"
#include "components/exo/test/shell_surface_builder.h"
#include "components/exo/wm_helper.h"
#include "services/accessibility/android/accessibility_info_data_wrapper.h"
#include "services/accessibility/android/android_accessibility_util.h"
#include "services/accessibility/android/ax_tree_source_android.h"
#include "services/accessibility/android/test/android_accessibility_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace arc {
class TestAccessibilityInfoDataWrapper
: public ax::android::AccessibilityInfoDataWrapper {
public:
explicit TestAccessibilityInfoDataWrapper(
ax::android::AXTreeSourceAndroid* tree_source_)
: AccessibilityInfoDataWrapper(tree_source_) {}
// AccessibilityInfoDataWrapper overrides:
bool IsNode() const override { return false; }
ax::android::mojom::AccessibilityNodeInfoData* GetNode() const override {
return nullptr;
}
ax::android::mojom::AccessibilityWindowInfoData* GetWindow() const override {
return nullptr;
}
int32_t GetId() const override { return id_; }
const gfx::Rect GetBounds() const override { return bounds_; }
bool IsVisibleToUser() const override { return true; }
bool IsWebNode() const override { return false; }
bool IsIgnored() const override { return false; }
bool IsImportantInAndroid() const override { return true; }
bool IsFocusableInFullFocusMode() const override { return true; }
bool IsAccessibilityFocusableContainer() const override { return true; }
void PopulateAXRole(ui::AXNodeData* out_data) const override {}
void PopulateAXState(ui::AXNodeData* out_data) const override {}
std::string ComputeAXName(bool do_recursive) const override { return ""; }
void GetChildren(
std::vector<raw_ptr<AccessibilityInfoDataWrapper, VectorExperimental>>*
children) const override {}
int32_t GetWindowId() const override { return 1; }
int32_t id_ = 1;
gfx::Rect bounds_;
};
class TestTreeSource : public ax::android::AXTreeSourceAndroid {
public:
explicit TestTreeSource(aura::Window* window)
: AXTreeSourceAndroid(nullptr,
std::make_unique<ArcSerializationDelegate>(),
window) {}
ax::android::AccessibilityInfoDataWrapper* GetRoot() const override {
return root_;
}
raw_ptr<ax::android::AccessibilityInfoDataWrapper> root_;
};
class ArcSerializationDelegateTest : public ChromeAshTestBase {
public:
ArcSerializationDelegateTest() = default;
std::unique_ptr<exo::WMHelper> wm_helper = std::make_unique<exo::WMHelper>();
};
TEST_F(ArcSerializationDelegateTest, NonRootNodeBounds) {
auto shell_surface = exo::test::ShellSurfaceBuilder({200, 200})
.SetGeometry(gfx::Rect(10, 10, 200, 200))
.BuildClientControlledShellSurface();
TestTreeSource tree_source(shell_surface->GetWidget()->GetNativeWindow());
TestAccessibilityInfoDataWrapper root(&tree_source);
root.bounds_ = gfx::Rect(10, 10, 200, 200);
tree_source.root_ = &root;
TestAccessibilityInfoDataWrapper data(&tree_source);
data.id_ = 2;
data.bounds_ = gfx::Rect(20, 20, 30, 40);
ui::AXNodeData out_data;
tree_source.serialization_delegate().PopulateBounds(data, out_data);
EXPECT_EQ(gfx::RectF(10, 10, 30, 40), out_data.relative_bounds.bounds);
}
TEST_F(ArcSerializationDelegateTest, RootNodeBounds) {
UpdateDisplay("400x300");
auto shell_surface = exo::test::ShellSurfaceBuilder({200, 200})
.SetGeometry(gfx::Rect(10, 10, 200, 200))
.BuildClientControlledShellSurface();
TestTreeSource tree_source(shell_surface->GetWidget()->GetNativeWindow());
TestAccessibilityInfoDataWrapper data(&tree_source);
data.bounds_ = gfx::Rect(10, 10, 200, 200);
tree_source.root_ = &data;
ui::AXNodeData out_data;
tree_source.serialization_delegate().PopulateBounds(data, out_data);
EXPECT_EQ(gfx::RectF(0, 0, 200, 200), out_data.relative_bounds.bounds);
}
TEST_F(ArcSerializationDelegateTest, RootNodeBoundsOnExternalDisplay) {
UpdateDisplay("400x300,600x500");
auto shell_surface = exo::test::ShellSurfaceBuilder({200, 200})
.SetGeometry(gfx::Rect(410, 10, 200, 200))
.BuildClientControlledShellSurface();
TestTreeSource tree_source(shell_surface->GetWidget()->GetNativeWindow());
TestAccessibilityInfoDataWrapper data(&tree_source);
data.bounds_ = gfx::Rect(10, 10, 200, 200);
tree_source.root_ = &data;
ui::AXNodeData out_data;
tree_source.serialization_delegate().PopulateBounds(data, out_data);
EXPECT_EQ(gfx::RectF(0, 0, 200, 200), out_data.relative_bounds.bounds);
}
TEST_F(ArcSerializationDelegateTest, BoundsScalingPiArc) {
UpdateDisplay("400x300*2"); // 2x device scale factor.
// With default_scale_cancellation, Android has default (1x) scale factor.
wm_helper->SetDefaultScaleCancellation(true);
auto shell_surface = exo::test::ShellSurfaceBuilder()
.SetGeometry(gfx::Rect(10, 10, 100, 100))
.EnableDefaultScaleCancellation()
.BuildClientControlledShellSurface();
TestTreeSource tree_source(shell_surface->GetWidget()->GetNativeWindow());
TestAccessibilityInfoDataWrapper data(&tree_source);
data.bounds_ = gfx::Rect(10, 10, 100, 100); // PX in Android.
tree_source.root_ = &data;
ui::AXNodeData out_data;
tree_source.serialization_delegate().PopulateBounds(data, out_data);
EXPECT_EQ(gfx::RectF(0, 0, 200, 200), out_data.relative_bounds.bounds);
}
TEST_F(ArcSerializationDelegateTest, BoundsScalingFromRvcArcAndLater) {
UpdateDisplay("400x300*2"); // 2x device scale factor.
// Without default_scale_cancellation, Android use the same (2x) scale factor.
wm_helper->SetDefaultScaleCancellation(false);
auto shell_surface = exo::test::ShellSurfaceBuilder({200, 200})
.SetGeometry(gfx::Rect(10, 10, 200, 200))
.BuildClientControlledShellSurface();
TestTreeSource tree_source(shell_surface->GetWidget()->GetNativeWindow());
TestAccessibilityInfoDataWrapper data(&tree_source);
data.bounds_ = gfx::Rect(20, 20, 200, 200); // PX in Android.
tree_source.root_ = &data;
ui::AXNodeData out_data;
tree_source.serialization_delegate().PopulateBounds(data, out_data);
EXPECT_EQ(gfx::RectF(0, 0, 200, 200), out_data.relative_bounds.bounds);
}
} // namespace arc