#ifndef ASH_EVENTS_ACCESSIBILITY_EVENT_REWRITER_H_
#define ASH_EVENTS_ACCESSIBILITY_EVENT_REWRITER_H_
#include <map>
#include <memory>
#include <queue>
#include <set>
#include "ash/ash_export.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "ui/base/ime/ash/input_method_manager.h"
#include "ui/events/devices/input_device.h"
#include "ui/events/event_rewriter.h"
#include "ui/events/keycodes/keyboard_codes_posix.h"
namespace ui {
class EventRewriterAsh;
}
namespace ash {
class AccessibilityEventRewriterDelegate;
enum class SwitchAccessCommand;
enum class MagnifierCommand;
class ASH_EXPORT AccessibilityEventRewriter
: public ui::EventRewriter,
public input_method::InputMethodManager::Observer {
public:
inline static const int kMaxPendingEvents = 40;
struct PendingEventInfo {
PendingEventInfo(unsigned int id,
std::unique_ptr<ui::Event> event,
ui::EventRewriter::Continuation continuation);
~PendingEventInfo();
PendingEventInfo(const PendingEventInfo&) = delete;
PendingEventInfo& operator=(const PendingEventInfo&) = delete;
unsigned int id;
std::unique_ptr<ui::Event> event;
ui::EventRewriter::Continuation continuation;
};
AccessibilityEventRewriter(ui::EventRewriterAsh* event_rewriter_ash,
AccessibilityEventRewriterDelegate* delegate);
AccessibilityEventRewriter(const AccessibilityEventRewriter&) = delete;
AccessibilityEventRewriter& operator=(const AccessibilityEventRewriter&) =
delete;
~AccessibilityEventRewriter() override;
void OnUnhandledSpokenFeedbackEvent(std::unique_ptr<ui::Event> event) const;
void ProcessPendingSpokenFeedbackEvent(unsigned int id, bool propagate);
void SendEventHelper(const ui::EventRewriter::Continuation continuation,
const ui::Event* event) const;
void SetSpokenFeedbackMv3KeyHandlingEnabled(bool enabled);
void SetKeyCodesForSwitchAccessCommand(
const std::map<int, std::set<std::string>>& key_codes,
SwitchAccessCommand command);
void set_chromevox_capture_all_keys(bool value) {
chromevox_capture_all_keys_ = value;
}
void set_send_mouse_events(bool value) { send_mouse_events_ = value; }
void set_suspend_switch_access_key_handling(bool suspend) {
suspend_switch_access_key_handling_ = suspend;
}
std::map<int, std::set<ui::InputDeviceType>>
switch_access_key_codes_to_capture_for_test() {
return switch_access_key_codes_to_capture_;
}
std::map<int, SwitchAccessCommand>
key_code_to_switch_access_command_map_for_test() {
return key_code_to_switch_access_command_;
}
private:
friend class ChromeVoxAccessibilityEventRewriterTest;
friend class ChromeVoxMv3AccessibilityEventRewriterTest;
friend class MouseKeysAccessibilityEventRewriterTest;
bool RewriteEventForChromeVox(const ui::Event& event,
const Continuation continuation);
bool RewriteEventForSwitchAccess(const ui::Event& event,
const Continuation continuation);
bool RewriteEventForMagnifier(const ui::Event& event,
const Continuation continuation);
void OnMagnifierKeyPressed(const ui::KeyEvent* event);
void OnMagnifierKeyReleased(const ui::KeyEvent* event);
void MaybeSendMouseEvent(const ui::Event& event);
ui::EventDispatchDetails RewriteEvent(
const ui::Event& event,
const Continuation continuation) override;
void InputMethodChanged(input_method::InputMethodManager* manager,
Profile* profile,
bool show_message) override;
void SendAllPendingSpokenFeedbackEvents();
base::WeakPtr<AccessibilityEventRewriter> GetWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
Continuation chromevox_continuation_;
raw_ptr<AccessibilityEventRewriterDelegate> delegate_ = nullptr;
bool send_mouse_events_ = false;
bool chromevox_capture_all_keys_ = false;
std::map<int, std::set<ui::InputDeviceType>>
switch_access_key_codes_to_capture_;
std::map<int, SwitchAccessCommand> key_code_to_switch_access_command_;
const raw_ptr<ui::EventRewriterAsh, DanglingUntriaged> event_rewriter_ash_;
bool suspend_switch_access_key_handling_ = false;
bool try_rewriting_positional_keys_for_chromevox_ = true;
bool chromevox_mv3_key_handling_enabled_ = false;
unsigned int next_pending_event_id_ = 0;
std::queue<PendingEventInfo> pending_key_events_;
base::ScopedObservation<input_method::InputMethodManager,
input_method::InputMethodManager::Observer>
observation_{this};
base::WeakPtrFactory<AccessibilityEventRewriter> weak_ptr_factory_{this};
};
}
#endif