File: peripheral_customization_event_rewriter.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (171 lines) | stat: -rw-r--r-- 6,607 bytes parent folder | download | duplicates (6)
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_