blob: 84edd85034544a4f65f272223c8481f7a790e0b8 [file] [log] [blame]
// 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/bin/a11y_manager/settings/settings_provider_impl.h"
#include <lib/syslog/cpp/logger.h>
#include <src/lib/fxl/logging.h>
#include "src/ui/a11y/bin/a11y_manager/util.h"
namespace a11y_manager {
// clang-format off
const std::array<float, 9> kIdentityMatrix = {
1, 0, 0,
0, 1, 0,
0, 0, 1};
// To read more information about following Matrix, please refer to Jira ticket
// MI4-2420 to get a link to document which explains them in more detail.
const std::array<float, 9> kColorInversionMatrix = {
0.402, -0.598, -0.599,
-1.174, -0.174, -1.175,
-0.228, -0.228, 0.772};
const std::array<float, 9> kCorrectProtanomaly = {
0.622774, 0.264275, 0.216821,
0.377226, 0.735725, -0.216821,
0.000000, -0.000000, 1.000000};
const std::array<float, 9> kCorrectDeuteranomaly = {
0.288299f, 0.052709f, -0.257912f,
0.711701f, 0.947291f, 0.257912f,
0.000000f, -0.000000f, 1.000000f};
const std::array<float, 9> kCorrectTritanomaly = {
1.000000f, 0.000000f, -0.000000f,
-0.805712f, 0.378838f, 0.104823f,
0.805712f, 0.621162f, 0.895177f};
// clang-format on
SettingsProviderImpl::SettingsProviderImpl() : binding_(this), settings_() {
settings_.set_magnification_enabled(false);
settings_.set_magnification_zoom_factor(1.0);
settings_.set_screen_reader_enabled(false);
settings_.set_color_inversion_enabled(false);
settings_.set_color_correction(fuchsia::accessibility::ColorCorrection::DISABLED);
settings_.set_color_adjustment_matrix(kIdentityMatrix);
}
void SettingsProviderImpl::Bind(
fidl::InterfaceRequest<fuchsia::accessibility::SettingsProvider> settings_provider_request) {
binding_.Close(ZX_ERR_PEER_CLOSED);
binding_.Bind(std::move(settings_provider_request));
}
std::string SettingsProviderImpl::BoolToString(bool value) { return value ? "true" : "false"; }
void SettingsProviderImpl::SetMagnificationEnabled(bool magnification_enabled,
SetMagnificationEnabledCallback callback) {
// Attempting to enable magnification when it's already enabled OR disable
// magnification when it's already disabled has no effect.
if (settings_.has_magnification_enabled() &&
settings_.magnification_enabled() == magnification_enabled) {
callback(fuchsia::accessibility::SettingsManagerStatus::OK);
return;
}
if (magnification_enabled) {
// Case: enable magnification (currently disabled).
settings_.set_magnification_enabled(true);
} else {
// Case: disable magnification (currently enabled).
settings_.set_magnification_enabled(false);
}
// In either case, set zoom factor to default value of 1.0.
settings_.set_magnification_zoom_factor(1.0);
NotifyWatchers(settings_);
FX_LOGS(INFO) << "magnification_enabled = " << BoolToString(settings_.magnification_enabled());
callback(fuchsia::accessibility::SettingsManagerStatus::OK);
}
void SettingsProviderImpl::SetMagnificationZoomFactor(float magnification_zoom_factor,
SetMagnificationZoomFactorCallback callback) {
if (!settings_.has_magnification_enabled() || !(settings_.magnification_enabled())) {
callback(fuchsia::accessibility::SettingsManagerStatus::ERROR);
return;
}
if (magnification_zoom_factor < 1.0) {
FX_LOGS(ERROR) << "Magnification zoom factor must be > 1.0.";
callback(fuchsia::accessibility::SettingsManagerStatus::ERROR);
return;
}
settings_.set_magnification_zoom_factor(magnification_zoom_factor);
NotifyWatchers(settings_);
FX_LOGS(INFO) << "magnification_zoom_factor = " << settings_.magnification_zoom_factor();
callback(fuchsia::accessibility::SettingsManagerStatus::OK);
}
void SettingsProviderImpl::SetScreenReaderEnabled(bool screen_reader_enabled,
SetScreenReaderEnabledCallback callback) {
settings_.set_screen_reader_enabled(screen_reader_enabled);
NotifyWatchers(settings_);
FX_LOGS(INFO) << "screen_reader_enabled = " << BoolToString(settings_.screen_reader_enabled());
callback(fuchsia::accessibility::SettingsManagerStatus::OK);
}
void SettingsProviderImpl::SetColorInversionEnabled(bool color_inversion_enabled,
SetColorInversionEnabledCallback callback) {
settings_.set_color_inversion_enabled(color_inversion_enabled);
settings_.set_color_adjustment_matrix(GetColorAdjustmentMatrix());
NotifyWatchers(settings_);
FX_LOGS(INFO) << "color_inversion_enabled = "
<< BoolToString(settings_.color_inversion_enabled());
callback(fuchsia::accessibility::SettingsManagerStatus::OK);
}
void SettingsProviderImpl::SetColorCorrection(
fuchsia::accessibility::ColorCorrection color_correction, SetColorCorrectionCallback callback) {
settings_.set_color_correction(color_correction);
settings_.set_color_adjustment_matrix(GetColorAdjustmentMatrix());
NotifyWatchers(settings_);
callback(fuchsia::accessibility::SettingsManagerStatus::OK);
}
void SettingsProviderImpl::NotifyWatchers(const fuchsia::accessibility::Settings& new_settings) {
for (auto& watcher : watchers_) {
auto setting = fidl::Clone(new_settings);
watcher->OnSettingsChange(std::move(setting));
}
}
void SettingsProviderImpl::ReleaseWatcher(fuchsia::accessibility::SettingsWatcher* watcher) {
auto predicate = [watcher](const auto& target) { return target.get() == watcher; };
watchers_.erase(std::remove_if(watchers_.begin(), watchers_.end(), predicate));
}
void SettingsProviderImpl::AddWatcher(
fidl::InterfaceHandle<fuchsia::accessibility::SettingsWatcher> watcher) {
fuchsia::accessibility::SettingsWatcherPtr watcher_proxy = watcher.Bind();
fuchsia::accessibility::SettingsWatcher* proxy_raw_ptr = watcher_proxy.get();
watcher_proxy.set_error_handler(
[this, proxy_raw_ptr](zx_status_t status) { ReleaseWatcher(proxy_raw_ptr); });
// Send Current Settings to watcher, so that they have the initial copy of the
// Settings.
auto setting = fidl::Clone(settings_);
watcher_proxy->OnSettingsChange(std::move(setting));
watchers_.push_back(std::move(watcher_proxy));
}
std::array<float, 9> SettingsProviderImpl::GetColorAdjustmentMatrix() {
std::array<float, 9> color_inversion_matrix = kIdentityMatrix;
std::array<float, 9> color_correction_matrix = kIdentityMatrix;
if (settings_.color_inversion_enabled()) {
color_inversion_matrix = kColorInversionMatrix;
}
switch (settings_.color_correction()) {
case fuchsia::accessibility::ColorCorrection::CORRECT_PROTANOMALY:
color_correction_matrix = kCorrectProtanomaly;
break;
case fuchsia::accessibility::ColorCorrection::CORRECT_DEUTERANOMALY:
color_correction_matrix = kCorrectDeuteranomaly;
break;
case fuchsia::accessibility::ColorCorrection::CORRECT_TRITANOMALY:
color_correction_matrix = kCorrectTritanomaly;
break;
case fuchsia::accessibility::ColorCorrection::DISABLED:
color_correction_matrix = kIdentityMatrix;
break;
}
return Multiply3x3MatrixRowMajor(color_inversion_matrix, color_correction_matrix);
}
} // namespace a11y_manager