blob: 45fb17a3c070716ff8cdf3070dbacc507bd50c2a [file] [log] [blame]
// Copyright 2018 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.
#ifndef SRC_UI_A11Y_BIN_A11Y_MANAGER_APP_H_
#define SRC_UI_A11Y_BIN_A11Y_MANAGER_APP_H_
#include <fuchsia/accessibility/cpp/fidl.h>
#include <fuchsia/accessibility/gesture/cpp/fidl.h>
#include <fuchsia/accessibility/virtualkeyboard/cpp/fidl.h>
#include <fuchsia/intl/cpp/fidl.h>
#include <fuchsia/settings/cpp/fidl.h>
#include <fuchsia/ui/focus/cpp/fidl.h>
#include <fuchsia/ui/input/accessibility/cpp/fidl.h>
#include <lib/fidl/cpp/binding.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/inspect/cpp/inspect.h>
#include <lib/sys/cpp/component_context.h>
#include <memory>
#include <optional>
#include "src/lib/fxl/macros.h"
#include "src/ui/a11y/lib/configuration/color_transform_manager.h"
#include "src/ui/a11y/lib/focus_chain/focus_chain_manager.h"
#include "src/ui/a11y/lib/gesture_manager/gesture_listener_registry.h"
#include "src/ui/a11y/lib/gesture_manager/gesture_manager_v2.h"
#include "src/ui/a11y/lib/magnifier/magnifier_2.h"
#include "src/ui/a11y/lib/screen_reader/screen_reader.h"
#include "src/ui/a11y/lib/tts/tts_manager.h"
#include "src/ui/a11y/lib/util/boot_info_manager.h"
#include "src/ui/a11y/lib/view/view_manager.h"
namespace a11y_manager {
// Internal representation of the current state of the accessibility manager features.
class A11yManagerState {
public:
// Default state with all values as disabled
A11yManagerState()
: color_correction_mode_(fuchsia::accessibility::ColorCorrectionMode::DISABLED) {}
// Copy constructor
A11yManagerState(const A11yManagerState& other) = default;
A11yManagerState& operator=(const A11yManagerState& other) = default;
bool screen_reader_enabled() const { return screen_reader_enabled_; }
bool magnifier_enabled() const { return magnifier_enabled_; }
bool color_inversion_enabled() const { return color_inversion_enabled_; }
bool announce_screen_reader_enabled() const { return announce_screen_reader_enabled_; }
void set_announce_screen_reader_enabled(bool announce_screen_reader_enabled) {
announce_screen_reader_enabled_ = announce_screen_reader_enabled;
}
fuchsia::accessibility::ColorCorrectionMode color_correction_mode() const {
return color_correction_mode_;
}
A11yManagerState withScreenReaderEnabled(bool enabled) {
A11yManagerState state = *this;
state.screen_reader_enabled_ = enabled;
return state;
}
A11yManagerState withMagnifierEnabled(bool enabled) {
A11yManagerState state = *this;
state.magnifier_enabled_ = enabled;
return state;
}
// Creates a new instance of state that has any set values from the given AccessibilitySettings
// applied.
A11yManagerState withSettings(const fuchsia::settings::AccessibilitySettings& systemSettings);
private:
bool screen_reader_enabled_ = false;
bool magnifier_enabled_ = false;
bool color_inversion_enabled_ = false;
// Indicates whether the screen reader should vocalize when initialized.
bool announce_screen_reader_enabled_ = false;
fuchsia::accessibility::ColorCorrectionMode color_correction_mode_;
};
// Represents the state of initialization of the a11y manager.
class A11yManagerInitializationState {
public:
using OnA11yManagerInitializedCallback = fit::function<void()>;
// The default ocnstructor constructs a state not initialized.
A11yManagerInitializationState() = default;
~A11yManagerInitializationState() = default;
// Sets a callback to be invoked when tthis state is considered to be initialized.
void SetOnA11yManagerInitializedCallback(OnA11yManagerInitializedCallback callback) {
callback_ = std::move(callback);
}
// Returns true if A11y manager has all its dependencies initialized.
bool IsInitialized() const { return has_i18N_profile_ && is_a11y_view_initialized_; }
void SetI18nProfileReady();
void SetA11yViewReady();
private:
OnA11yManagerInitializedCallback callback_;
bool has_i18N_profile_ = false;
bool is_a11y_view_initialized_ = false;
};
// A11y manager application entry point.
class App {
public:
// App dependencies which are trivial to set up and contribute to easier test should be
// passed in the constructor.
explicit App(sys::ComponentContext* context, a11y::ViewManager* view_manager,
a11y::TtsManager* tts_manager, a11y::ColorTransformManager* color_transform_manager,
a11y::GestureListenerRegistry* gesture_listener_registry,
a11y::BootInfoManager* boot_info_manager,
a11y::ScreenReaderContextFactory* screen_reader_context_factory,
inspect::Node inspect_node = inspect::Node());
~App();
// Sets the a11y manager to the given configuration. Visible for testing.
void SetState(A11yManagerState newState);
A11yManagerState state() { return state_; }
a11y::ScreenReader* screen_reader() { return screen_reader_.get(); }
static constexpr char kIntlPropertyProviderDisconnectedInspectName[] =
"intl_property_provider_disconnected";
static constexpr char kScreenReaderEnabledInspectName[] = "screen_reader_enabled";
static constexpr char kMagnifierEnabledInspectName[] = "magnifier_enabled";
static constexpr char kColorInversionEnabledInspectName[] = "color_inversion_enabled";
static constexpr char kColorCorrectionModeInspectName[] = "color_correction_mode";
private:
// If gesture manager/handler/arena ever get idempotent operations, we can remove this.
struct GestureState {
bool screen_reader_gestures = false;
bool magnifier_gestures = false;
bool has_any() const { return screen_reader_gestures || magnifier_gestures; }
bool operator==(GestureState o) const;
};
// Finishes the SetUp of this object. For now, only the fetch of the current settings is called
// here. If any condition needs this object to be fully-initialized (all class members are
// initialized), they must be invoked here. For example: the field |profile_| is only available
// after this object is initialized, and settings relly on this field to process its logic. Trying
// to handle the settings logic without |profile_| would result in an error.
void FinishSetUp();
// Callback for Setui's Watch() method.
void SetuiWatchCallback(fuchsia::settings::AccessibilitySettings settings);
// Set up continuous watch of setui's accessibility settings. The Watch(...) method returns on
// the initial call, and afterwards uses a hanging get to return only when settings change.
void WatchSetui();
void UpdateScreenReaderState();
void UpdateMagnifierState();
void UpdateColorTransformState();
void UpdateGestureManagerState();
void UpdateInspectState();
// Initializes the Screen Reader, instantiating its context and related services.
std::unique_ptr<a11y::ScreenReader> InitializeScreenReader();
// |fuchsia.intl.PropertyProvider|
// Handler invoked when the FIDL event OnChange is called.
// Fetches the user's i18n profile and stores in |i18n_profile_|.
void PropertyProviderOnChangeHandler();
// Data fields that must be initialized to consider this object as initialized.
// Current state of the a11y manager
A11yManagerState state_;
A11yManagerInitializationState initialization_state_;
// The user's i18n profile.
std::optional<fuchsia::intl::Profile> i18n_profile_;
// End of list of data fields that must be set to consider this object initialized.
sys::ComponentContext* context_;
std::unique_ptr<a11y::ScreenReader> screen_reader_;
a11y::ViewManager* view_manager_;
a11y::TtsManager* tts_manager_;
a11y::ColorTransformManager* color_transform_manager_;
a11y::GestureListenerRegistry* gesture_listener_registry_;
a11y::ScreenReaderContextFactory* screen_reader_context_factory_;
std::unique_ptr<a11y::FocusChainManager> focus_chain_manager_;
// The gesture manager is instantiated whenever a11y manager starts listening
// for pointer events, and destroyed when the listener disconnects.
std::unique_ptr<a11y::GestureManagerV2> gesture_manager_;
GestureState gesture_state_;
std::unique_ptr<a11y::Magnifier2> magnifier_;
fidl::BindingSet<fuchsia::accessibility::semantics::SemanticsManager> semantics_manager_bindings_;
fidl::BindingSet<fuchsia::accessibility::virtualkeyboard::Registry>
virtualkeyboard_registry_bindings_;
fidl::BindingSet<fuchsia::ui::focus::FocusChainListener> focus_chain_listener_bindings_;
fidl::BindingSet<fuchsia::accessibility::Magnifier> magnifier_bindings_;
fidl::BindingSet<fuchsia::accessibility::gesture::ListenerRegistry>
gesture_listener_registry_bindings_;
// Interface between Setui and a11y manager to get updates when user settings change.
fuchsia::settings::AccessibilityPtr setui_settings_;
// Interface used to retrieve the current locale and watch when it changes.
fuchsia::intl::PropertyProviderPtr property_provider_;
// Inspect node to which to publish debug info.
inspect::Node inspect_node_;
// Inspect property indicating whether a locale was found.
// If false, the a11y manager could not connect to the PropertyProvider, and
// defaulted to the locale "en-US".
inspect::BoolProperty inspect_property_intl_property_provider_disconnected_;
// Inspect properties for each of the user configurable features.
inspect::BoolProperty screen_reader_enabled_;
inspect::BoolProperty magnifier_enabled_;
inspect::BoolProperty color_inversion_enabled_;
inspect::UintProperty color_correction_mode_;
FXL_DISALLOW_COPY_AND_ASSIGN(App);
};
} // namespace a11y_manager
#endif // SRC_UI_A11Y_BIN_A11Y_MANAGER_APP_H_