| // Copyright 2019 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "src/ui/a11y/lib/configuration/color_transform_manager.h" |
| |
| #include <fuchsia/accessibility/cpp/fidl.h> |
| #include <lib/fidl/cpp/binding_set.h> |
| #include <lib/sys/cpp/testing/component_context_provider.h> |
| #include <lib/syslog/cpp/macros.h> |
| |
| #include <cmath> |
| |
| #include <gtest/gtest.h> |
| |
| #include "src/lib/testing/loop_fixture/test_loop_fixture.h" |
| |
| namespace accessibility_test { |
| namespace { |
| |
| // clang-format off |
| const std::array<float, 9> kIdentityMatrix = { |
| 1, 0, 0, |
| 0, 1, 0, |
| 0, 0, 1}; |
| const std::array<float, 3> kZero3x1Vector = {0, 0, 0}; |
| |
| const std::array<float, 9> kColorInversionMatrix = { |
| 0.402f, -1.174f, -0.228f, |
| -0.598f, -0.174f, -0.228f, |
| -0.599f, -1.177f, 0.771f}; |
| const std::array<float, 3> kColorInversionPostOffset = {.999f, .999f, .999f}; |
| |
| const std::array<float, 9> kCorrectProtanomaly = { |
| 0.622774, 0.377226, 0.000000, |
| 0.264275, 0.735725, -0.000000, |
| 0.216821, -0.216821, 1.000000}; |
| |
| const std::array<float, 9> kProtanomalyAndInversionMatrix = { |
| -0.10933889, -0.66266111, -0.228, |
| -0.46783789, -0.30416211, -0.228, |
| -0.51692431, -1.25907569, 0.771}; |
| const std::array<float, 3> kProtanomalyAndInversionPostOffset = {.999f, .999f, .999f}; |
| |
| // clang-format on |
| |
| class FakeColorTransformHandler : public fuchsia::accessibility::ColorTransformHandler { |
| public: |
| FakeColorTransformHandler() = default; |
| ~FakeColorTransformHandler() = default; |
| |
| fidl::InterfaceHandle<fuchsia::accessibility::ColorTransformHandler> GetHandle() { |
| return bindings_.AddBinding(this); |
| } |
| |
| // |fuchsia.accessibility.ColorTransformHandler| |
| void SetColorTransformConfiguration( |
| fuchsia::accessibility::ColorTransformConfiguration configuration, |
| SetColorTransformConfigurationCallback callback) { |
| transform_ = configuration.has_color_adjustment_matrix() |
| ? configuration.color_adjustment_matrix() |
| : kIdentityMatrix; |
| pre_offset_ = configuration.has_color_adjustment_pre_offset() |
| ? configuration.color_adjustment_pre_offset() |
| : kZero3x1Vector; |
| post_offset_ = configuration.has_color_adjustment_post_offset() |
| ? configuration.color_adjustment_post_offset() |
| : kZero3x1Vector; |
| |
| color_inversion_enabled_ = configuration.has_color_inversion_enabled() |
| ? configuration.color_inversion_enabled() |
| : false; |
| |
| color_correction_mode_ = configuration.has_color_correction() |
| ? configuration.color_correction() |
| : fuchsia::accessibility::ColorCorrectionMode::DISABLED; |
| callback(); |
| } |
| |
| bool hasTransform(std::array<float, 9> transform_to_compare) const { |
| return FloatArraysAreEqual(transform_, transform_to_compare); |
| } |
| |
| bool hasPostOffset(std::array<float, 3> offset_to_compare) const { |
| return FloatArraysAreEqual(post_offset_, offset_to_compare); |
| } |
| |
| fidl::BindingSet<fuchsia::accessibility::ColorTransformHandler> bindings_; |
| std::array<float, 9> transform_; |
| std::array<float, 3> pre_offset_; |
| std::array<float, 3> post_offset_; |
| |
| // These fields `has_value()` iff SetColorTransformConfiguration() has been called. |
| std::optional<bool> color_inversion_enabled_; |
| std::optional<fuchsia::accessibility::ColorCorrectionMode> color_correction_mode_; |
| |
| private: |
| template <size_t N> |
| static bool FloatArraysAreEqual(const std::array<float, N>& a, const std::array<float, N>& b) { |
| const float float_comparison_epsilon = 0.00001; |
| for (size_t i = 0; i < N; i++) { |
| if ((std::fabs(a[i] - b[i]) > float_comparison_epsilon)) { |
| return false; |
| } |
| } |
| return true; |
| } |
| }; |
| |
| class ColorTransformManagerTest : public gtest::TestLoopFixture { |
| public: |
| ColorTransformManagerTest() = default; |
| ~ColorTransformManagerTest() override = default; |
| |
| void SetUp() override { |
| TestLoopFixture::SetUp(); |
| |
| startup_context_ = sys::ComponentContext::CreateAndServeOutgoingDirectory(); |
| color_transform_manager_ = |
| std::make_unique<a11y::ColorTransformManager>(startup_context_.get()); |
| |
| RunLoopUntilIdle(); |
| } |
| |
| std::unique_ptr<sys::ComponentContext> startup_context_; |
| std::unique_ptr<a11y::ColorTransformManager> color_transform_manager_; |
| FakeColorTransformHandler color_transform_handler_; |
| fidl::BindingSet<fuchsia::accessibility::ColorTransform> color_transform_bindings_; |
| }; |
| |
| TEST_F(ColorTransformManagerTest, NoHandler) { |
| // change a setting |
| color_transform_manager_->ChangeColorTransform( |
| false, fuchsia::accessibility::ColorCorrectionMode::DISABLED); |
| RunLoopUntilIdle(); |
| |
| // This test is verifying that nothing crashes. |
| } |
| |
| TEST_F(ColorTransformManagerTest, SetColorTransformDefault) { |
| // register a (fake) handler |
| color_transform_manager_->RegisterColorTransformHandler(color_transform_handler_.GetHandle()); |
| |
| // change a setting |
| color_transform_manager_->ChangeColorTransform( |
| false, fuchsia::accessibility::ColorCorrectionMode::DISABLED); |
| RunLoopUntilIdle(); |
| |
| // Verify handler gets sent the correct settings. |
| ASSERT_TRUE(color_transform_handler_.color_inversion_enabled_.has_value()); |
| EXPECT_FALSE(color_transform_handler_.color_inversion_enabled_.value()); |
| ASSERT_TRUE(color_transform_handler_.color_correction_mode_.has_value()); |
| EXPECT_EQ(color_transform_handler_.color_correction_mode_.value(), |
| fuchsia::accessibility::ColorCorrectionMode::DISABLED); |
| EXPECT_TRUE(color_transform_handler_.hasTransform(kIdentityMatrix)); |
| } |
| |
| TEST_F(ColorTransformManagerTest, SetColorInversionEnabled) { |
| // register a (fake) handler |
| color_transform_manager_->RegisterColorTransformHandler(color_transform_handler_.GetHandle()); |
| |
| // change a setting |
| color_transform_manager_->ChangeColorTransform( |
| true, fuchsia::accessibility::ColorCorrectionMode::DISABLED); |
| RunLoopUntilIdle(); |
| |
| // Verify handler gets sent the correct settings. |
| ASSERT_TRUE(color_transform_handler_.color_inversion_enabled_.has_value()); |
| EXPECT_TRUE(color_transform_handler_.color_inversion_enabled_.value()); |
| ASSERT_TRUE(color_transform_handler_.color_correction_mode_.has_value()); |
| EXPECT_EQ(color_transform_handler_.color_correction_mode_.value(), |
| fuchsia::accessibility::ColorCorrectionMode::DISABLED); |
| EXPECT_TRUE(color_transform_handler_.hasTransform(kColorInversionMatrix)); |
| EXPECT_TRUE(color_transform_handler_.hasPostOffset(kColorInversionPostOffset)); |
| } |
| |
| TEST_F(ColorTransformManagerTest, SetColorCorrection) { |
| // register a (fake) handler |
| color_transform_manager_->RegisterColorTransformHandler(color_transform_handler_.GetHandle()); |
| |
| // change a setting |
| color_transform_manager_->ChangeColorTransform( |
| false, fuchsia::accessibility::ColorCorrectionMode::CORRECT_PROTANOMALY); |
| RunLoopUntilIdle(); |
| |
| // Verify handler gets sent the correct settings. |
| ASSERT_TRUE(color_transform_handler_.color_inversion_enabled_.has_value()); |
| EXPECT_FALSE(color_transform_handler_.color_inversion_enabled_.value()); |
| ASSERT_TRUE(color_transform_handler_.color_correction_mode_.has_value()); |
| EXPECT_EQ(color_transform_handler_.color_correction_mode_.value(), |
| fuchsia::accessibility::ColorCorrectionMode::CORRECT_PROTANOMALY); |
| EXPECT_TRUE(color_transform_handler_.hasTransform(kCorrectProtanomaly)); |
| } |
| |
| TEST_F(ColorTransformManagerTest, SetColorCorrectionAndInversion) { |
| // register a (fake) handler |
| color_transform_manager_->RegisterColorTransformHandler(color_transform_handler_.GetHandle()); |
| |
| // change a setting |
| color_transform_manager_->ChangeColorTransform( |
| true, fuchsia::accessibility::ColorCorrectionMode::CORRECT_PROTANOMALY); |
| RunLoopUntilIdle(); |
| |
| // Verify handler gets sent the correct settings. |
| ASSERT_TRUE(color_transform_handler_.color_inversion_enabled_.has_value()); |
| EXPECT_TRUE(color_transform_handler_.color_inversion_enabled_.value()); |
| ASSERT_TRUE(color_transform_handler_.color_correction_mode_.has_value()); |
| EXPECT_EQ(color_transform_handler_.color_correction_mode_.value(), |
| fuchsia::accessibility::ColorCorrectionMode::CORRECT_PROTANOMALY); |
| EXPECT_TRUE(color_transform_handler_.hasTransform(kProtanomalyAndInversionMatrix)); |
| EXPECT_TRUE(color_transform_handler_.hasPostOffset(kProtanomalyAndInversionPostOffset)); |
| } |
| |
| TEST_F(ColorTransformManagerTest, BuffersChangeBeforeHandlerRegistered) { |
| // Enable color inversion and color correction. |
| color_transform_manager_->ChangeColorTransform( |
| true, fuchsia::accessibility::ColorCorrectionMode::CORRECT_DEUTERANOMALY); |
| RunLoopUntilIdle(); |
| |
| // Register the (fake) handler. |
| color_transform_manager_->RegisterColorTransformHandler(color_transform_handler_.GetHandle()); |
| RunLoopUntilIdle(); |
| |
| // Verify handler gets sent the correct settings. |
| ASSERT_TRUE(color_transform_handler_.color_inversion_enabled_.has_value()); |
| EXPECT_TRUE(color_transform_handler_.color_inversion_enabled_.value()); |
| ASSERT_TRUE(color_transform_handler_.color_correction_mode_.has_value()); |
| EXPECT_EQ(color_transform_handler_.color_correction_mode_.value(), |
| fuchsia::accessibility::ColorCorrectionMode::CORRECT_DEUTERANOMALY); |
| } |
| |
| TEST_F(ColorTransformManagerTest, ReappliesSettingOnHandlerChange) { |
| // Enable color inversion and color correction. |
| color_transform_manager_->ChangeColorTransform( |
| true, fuchsia::accessibility::ColorCorrectionMode::CORRECT_DEUTERANOMALY); |
| RunLoopUntilIdle(); |
| |
| // Register the (fake) handler. |
| color_transform_manager_->RegisterColorTransformHandler(color_transform_handler_.GetHandle()); |
| RunLoopUntilIdle(); |
| |
| // Create and register a new (fake) handler. |
| FakeColorTransformHandler new_handler; |
| color_transform_manager_->RegisterColorTransformHandler(new_handler.GetHandle()); |
| RunLoopUntilIdle(); |
| |
| // Verify the new handler gets sent the correct settings. |
| ASSERT_TRUE(new_handler.color_inversion_enabled_.has_value()); |
| EXPECT_TRUE(new_handler.color_inversion_enabled_.value()); |
| ASSERT_TRUE(new_handler.color_correction_mode_.has_value()); |
| EXPECT_EQ(new_handler.color_correction_mode_.value(), |
| fuchsia::accessibility::ColorCorrectionMode::CORRECT_DEUTERANOMALY); |
| } |
| |
| } // namespace |
| } // namespace accessibility_test |