1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
|
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_EVENTS_PERIPHERAL_CUSTOMIZATION_EVENT_REWRITER_H_
#define ASH_EVENTS_PERIPHERAL_CUSTOMIZATION_EVENT_REWRITER_H_
#include "ash/ash_export.h"
#include "ash/public/mojom/input_device_settings.mojom-forward.h"
#include "ash/public/mojom/input_device_settings.mojom.h"
#include "ash/system/input_device_settings/input_device_settings_metrics_manager.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/memory/raw_ptr.h"
#include "base/observer_list.h"
#include "base/observer_list_types.h"
#include "ui/events/event.h"
#include "ui/events/event_dispatcher.h"
#include "ui/events/event_rewriter.h"
namespace ash {
class InputDeviceSettingsController;
// PeripheralCustomizationEventRewriter recognizes and rewrites events from mice
// and graphics tablets to arbitrary `ui::KeyEvent`s configured by the user via
// the Settings SWA.
class ASH_EXPORT PeripheralCustomizationEventRewriter
: public ui::EventRewriter {
public:
using ButtonRemappingList =
std::vector<std::pair<mojom::ButtonPtr, mojom::RemappingActionPtr>>;
enum class DeviceType { kMouse, kGraphicsTablet };
struct DeviceIdButton {
int device_id;
mojom::ButtonPtr button;
DeviceIdButton(int device_id, mojom::ButtonPtr button);
DeviceIdButton(DeviceIdButton&& device_id_button);
~DeviceIdButton();
DeviceIdButton& operator=(DeviceIdButton&& device_id_button);
friend bool operator<(const DeviceIdButton& left,
const DeviceIdButton& right);
};
struct RemappingActionResult {
raw_ref<mojom::RemappingAction> remapping_action;
InputDeviceSettingsMetricsManager::PeripheralCustomizationMetricsType
peripheral_kind;
RemappingActionResult(
mojom::RemappingAction& remapping_action,
InputDeviceSettingsMetricsManager::PeripheralCustomizationMetricsType
peripheral_kind);
RemappingActionResult(RemappingActionResult&& result);
~RemappingActionResult();
};
explicit PeripheralCustomizationEventRewriter(
InputDeviceSettingsController* input_device_settings_controller);
PeripheralCustomizationEventRewriter(
const PeripheralCustomizationEventRewriter&) = delete;
PeripheralCustomizationEventRewriter& operator=(
const PeripheralCustomizationEventRewriter&) = delete;
~PeripheralCustomizationEventRewriter() override;
// Starts observing and blocking mouse events for `device_id`. Notifies
// observers via `OnMouseButtonPressed` whenever an event
void StartObservingMouse(
int device_id,
mojom::CustomizationRestriction customization_restriction);
// Starts observing and blocking graphics tablet events for `device_id`.
// Notifies observers via `OnGraphicsTabletButtonPressed` whenever an event is
// received.
void StartObservingGraphicsTablet(
int device_id,
mojom::CustomizationRestriction customization_restriction);
// Stops observing for all devices of every type.
void StopObserving();
// ui::EventRewriter:
ui::EventDispatchDetails RewriteEvent(
const ui::Event& event,
const Continuation continuation) override;
const base::flat_map<int, mojom::CustomizationRestriction>&
mice_to_observe() {
return mice_to_observe_;
}
const base::flat_map<int, mojom::CustomizationRestriction>&
graphics_tablets_to_observe() {
return graphics_tablets_to_observe_;
}
private:
// Notifies observers if the given `mouse_event` is a remappable button for
// the given `device_type`. Returns true if the event should be discarded.
bool NotifyMouseEventObserving(const ui::MouseEvent& mouse_event,
DeviceType device_type);
// Notifies observers if the given `mouse_wheel_event` is a remappable button
// for the given `device_type`. Returns true if the event should be discarded.
bool NotifyMouseWheelEventObserving(
const ui::MouseWheelEvent& mouse_wheel_event,
DeviceType device_type);
// Notifies observers if the given `key_event` is a remappable button for
// the given `device_type`. Returns true if the event should be discarded.
bool NotifyKeyEventObserving(const ui::KeyEvent& key_event,
DeviceType device_type);
// Returns if the button is customizable.
bool IsButtonCustomizable(const ui::KeyEvent& key_event);
// Rewrites the given event that came from `button` within the
// `rewritten_event` param. Returns true if the original event should be
// discarded.
bool RewriteEventFromButton(
const ui::Event& event,
const mojom::Button& button,
std::vector<std::unique_ptr<ui::Event>>& rewritten_event);
ui::EventDispatchDetails RewriteMouseEvent(const ui::MouseEvent& mouse_event,
const Continuation continuation);
ui::EventDispatchDetails RewriteMouseWheelEvent(
const ui::MouseWheelEvent& mouse_event,
const Continuation continuation);
ui::EventDispatchDetails RewriteKeyEvent(const ui::KeyEvent& key_event,
const Continuation continuation);
std::optional<DeviceType> GetDeviceTypeToObserve(int device_id);
std::optional<RemappingActionResult> GetRemappingAction(
int device_id,
const mojom::Button& button);
void UpdatePressedButtonMap(
mojom::ButtonPtr button,
const ui::Event& original_event,
const std::vector<std::unique_ptr<ui::Event>>& rewritten_event);
void UpdatePressedButtonMapFlags(const ui::KeyEvent& key_event);
// Removes the set of remapped modifiers from the event that should be
// discarded.
void RemoveRemappedModifiers(ui::Event& event);
// Applies all remapped modifiers.
void ApplyRemappedModifiers(ui::Event& event);
std::unique_ptr<ui::Event> CloneEvent(const ui::Event& event);
base::flat_map<int, mojom::CustomizationRestriction> mice_to_observe_;
base::flat_map<int, mojom::CustomizationRestriction>
graphics_tablets_to_observe_;
// Maintains a list of currently pressed buttons and the flags that should
// be applied to other events processed.
base::flat_map<DeviceIdButton, int> device_button_to_flags_;
raw_ptr<InputDeviceSettingsController> input_device_settings_controller_;
// Emit all metrics.
std::unique_ptr<InputDeviceSettingsMetricsManager> metrics_manager_;
};
} // namespace ash
#endif // ASH_EVENTS_PERIPHERAL_CUSTOMIZATION_EVENT_REWRITER_H_
|