summaryrefslogtreecommitdiff
path: root/chromium/ui/events/ozone/evdev/touch_event_converter_evdev.h
blob: 276d71e2c9fa68539918d0bf9159011cf3c42e38 (plain)
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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
// Copyright 2014 The Chromium 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 UI_EVENTS_OZONE_EVDEV_TOUCH_EVENT_CONVERTER_EVDEV_H_
#define UI_EVENTS_OZONE_EVDEV_TOUCH_EVENT_CONVERTER_EVDEV_H_

#include <linux/input.h>
#include <stddef.h>
#include <stdint.h>

#include <bitset>
#include <memory>
#include <queue>
// See if we compile against new enough headers and add missing definition
// if the headers are too old.
#ifndef MT_TOOL_PALM
#define MT_TOOL_PALM 2
#endif

#include "base/compiler_specific.h"
#include "base/component_export.h"
#include "base/files/file_path.h"
#include "base/files/scoped_file.h"
#include "base/macros.h"
#include "base/message_loop/message_pump_libevent.h"
#include "base/metrics/field_trial_params.h"
#include "ui/events/ozone/evdev/event_converter_evdev.h"
#include "ui/events/ozone/evdev/event_device_info.h"
#include "ui/events/ozone/evdev/touch_evdev_debug_buffer.h"
#include "ui/events/ozone/evdev/touch_filter/palm_detection_filter.h"
#include "ui/events/types/event_type.h"

namespace ui {

class DeviceEventDispatcherEvdev;
class FalseTouchFinder;
struct InProgressTouchEvdev;

COMPONENT_EXPORT(EVDEV) extern const base::Feature kEnableSingleCancelTouch;

class COMPONENT_EXPORT(EVDEV) TouchEventConverterEvdev
    : public EventConverterEvdev {
 public:
  TouchEventConverterEvdev(base::ScopedFD fd,
                           base::FilePath path,
                           int id,
                           const EventDeviceInfo& devinfo,
                           SharedPalmDetectionFilterState* shared_palm_state,
                           DeviceEventDispatcherEvdev* dispatcher);
  ~TouchEventConverterEvdev() override;

  static std::unique_ptr<TouchEventConverterEvdev> Create(
      base::ScopedFD fd,
      base::FilePath path,
      int id,
      const EventDeviceInfo& devinfo,
      SharedPalmDetectionFilterState* shared_palm_state,
      DeviceEventDispatcherEvdev* dispatcher);

  // EventConverterEvdev:
  bool HasTouchscreen() const override;
  bool HasPen() const override;
  gfx::Size GetTouchscreenSize() const override;
  int GetTouchPoints() const override;
  void OnEnabled() override;
  void OnDisabled() override;

  void DumpTouchEventLog(const char* filename) override;

  // Update touch event logging state
  void SetTouchEventLoggingEnabled(bool enabled) override;

  // Sets callback to enable/disable palm suppression.
  void SetPalmSuppressionCallback(
      const base::RepeatingCallback<void(bool)>& callback) override;

  // Unsafe part of initialization.
  virtual void Initialize(const EventDeviceInfo& info);

  static const char kHoldCountAtReleaseEventName[];
  static const char kHoldCountAtCancelEventName[];
  static const char kPalmFilterTimerEventName[];

 private:
  friend class MockTouchEventConverterEvdev;

  // Overidden from base::MessagePumpLibevent::FdWatcher.
  void OnFileCanReadWithoutBlocking(int fd) override;

  virtual void Reinitialize();

  void ProcessMultitouchEvent(const input_event& input);
  void EmulateMultitouchEvent(const input_event& input);
  void ProcessKey(const input_event& input);
  void ProcessAbs(const input_event& input);
  void ProcessSyn(const input_event& input);

  // Returns an EventType to dispatch for |touch|. Returns ET_UNKNOWN if an
  // event should not be dispatched.
  EventType GetEventTypeForTouch(const InProgressTouchEvdev& touch);

  void ReportTouchEvent(const InProgressTouchEvdev& event,
                        EventType event_type,
                        base::TimeTicks timestamp);
  void ReportEvents(base::TimeTicks timestamp);

  void ProcessTouchEvent(InProgressTouchEvdev* event,
                         base::TimeTicks timestamp);

  void UpdateTrackingId(int slot, int tracking_id);
  void ReleaseTouches();

  // Returns true if all touches were marked cancelled. Otherwise false.
  bool MaybeCancelAllTouches();
  bool IsPalm(const InProgressTouchEvdev& touch);

  // Normalize pressure value to [0, 1].
  float ScalePressure(int32_t value) const;

  int NextTrackingId();

  // Input device file descriptor.
  const base::ScopedFD input_device_fd_;

  // Dispatcher for events.
  DeviceEventDispatcherEvdev* const dispatcher_;

  // Set if we drop events in kernel (SYN_DROPPED) or in process.
  bool dropped_events_ = false;

  // Device has multitouch capability.
  bool has_mt_ = false;

  // Device supports pen input.
  bool has_pen_ = false;

  // Use BTN_LEFT instead of BT_TOUCH.
  bool quirk_left_mouse_button_ = false;

  // Pressure values.
  int pressure_min_;
  int pressure_max_;  // Used to normalize pressure values.

  // Input range for tilt.
  int tilt_x_min_;
  int tilt_x_range_;
  int tilt_y_min_;
  int tilt_y_range_;

  // Input range for x-axis.
  float x_min_tuxels_;
  float x_num_tuxels_;

  // Input range for y-axis.
  float y_min_tuxels_;
  float y_num_tuxels_;

  // The resolution of ABS_MT_TOUCH_MAJOR/MINOR might be different from the
  // resolution of ABS_MT_POSITION_X/Y. As we use the (position range, display
  // pixels) to resize touch event radius, we have to scale major/minor.
  float touch_major_scale_ = 1.0f;
  float touch_minor_scale_ = 1.0f;

  // Number of touch points reported by driver
  int touch_points_ = 0;

  // Maximum value of touch major axis
  int major_max_ = 0;

  // Tracking id counter.
  int next_tracking_id_ = 0;

  // Touch point currently being updated from the /dev/input/event* stream.
  size_t current_slot_ = 0;

  // Flag that indicates if the touch logging enabled or not.
  bool touch_logging_enabled_ = true;

  // In-progress touch points.
  std::vector<InProgressTouchEvdev> events_;

  // In progress touch points, from being held, along with the timestamp they
  // were held at.
  std::vector<std::queue<std::pair<InProgressTouchEvdev, base::TimeTicks>>>
      held_events_;

  // Finds touches that need to be filtered.
  std::unique_ptr<FalseTouchFinder> false_touch_finder_;

  // Finds touches that are palms with user software not just firmware.
  const std::unique_ptr<PalmDetectionFilter> palm_detection_filter_;

  // Records the recent touch events. It is used to fill the feedback reports
  TouchEventLogEvdev touch_evdev_debug_buffer_;

  // Callback to enable/disable palm suppression.
  base::RepeatingCallback<void(bool)> enable_palm_suppression_callback_;

  // Do we mark a touch as palm when touch_major is the max?
  bool palm_on_touch_major_max_;

  // Do we mark a touch as palm when the tool type is marked as TOOL_TYPE_PALM ?
  bool palm_on_tool_type_palm_;

  DISALLOW_COPY_AND_ASSIGN(TouchEventConverterEvdev);
};

}  // namespace ui

#endif  // UI_EVENTS_OZONE_EVDEV_TOUCH_EVENT_CONVERTER_EVDEV_H_