1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef ASH_DISPLAY_TOUCH_CALIBRATOR_TOUCH_CALIBRATOR_CONTROLLER_H_
6 #define ASH_DISPLAY_TOUCH_CALIBRATOR_TOUCH_CALIBRATOR_CONTROLLER_H_
7 
8 #include <map>
9 
10 #include "ash/ash_export.h"
11 #include "ash/display/window_tree_host_manager.h"
12 #include "base/time/time.h"
13 #include "ui/display/display.h"
14 #include "ui/display/manager/managed_display_info.h"
15 #include "ui/events/devices/touchscreen_device.h"
16 #include "ui/events/event_handler.h"
17 #include "ui/views/widget/unique_widget_ptr.h"
18 
19 namespace ui {
20 class KeyEvent;
21 class TouchEvent;
22 }  // namespace ui
23 
24 namespace ash {
25 
26 class TouchCalibratorView;
27 
28 // TouchCalibratorController is responsible for managing the touch calibration
29 // process. In case of native touch calibration it is also responsible for
30 // collecting the touch calibration associated data from the user. It
31 // instantiates TouchCalibratorView classes to present the native UX interface
32 // the user can interact with for calibration.
33 // This controller ensures that only one instance of calibration is running at
34 // any given time.
35 class ASH_EXPORT TouchCalibratorController
36     : public ui::EventHandler,
37       public WindowTreeHostManager::Observer {
38  public:
39   using CalibrationPointPairQuad =
40       display::TouchCalibrationData::CalibrationPointPairQuad;
41   using TouchCalibrationCallback = base::OnceCallback<void(bool)>;
42 
43   static const base::TimeDelta kTouchIntervalThreshold;
44 
45   TouchCalibratorController();
46   ~TouchCalibratorController() override;
47 
48   // ui::EventHandler
49   void OnKeyEvent(ui::KeyEvent* event) override;
50   void OnTouchEvent(ui::TouchEvent* event) override;
51 
52   // WindowTreeHostManager::Observer
53   void OnDisplayConfigurationChanged() override;
54 
55   // Starts the calibration process for the given |target_display|.
56   // |opt_callback| is an optional callback that if provided is executed
57   // with the success or failure of the calibration as a boolean argument.
58   void StartCalibration(const display::Display& target_display,
59                         bool is_custom_calibration,
60                         TouchCalibrationCallback opt_callback);
61 
62   // Stops any ongoing calibration process. This is a hard stop which does not
63   // save any calibration data. Call CompleteCalibration() if you wish to save
64   // calibration data.
65   void StopCalibrationAndResetParams();
66 
67   // Completes the touch calibration by storing the calibration data for the
68   // display.
69   void CompleteCalibration(const CalibrationPointPairQuad& pairs,
70                            const gfx::Size& display_size);
71 
72   // Returns true if any type of touch calibration is active.
73   bool IsCalibrating() const;
74 
75  private:
76   friend class TouchCalibratorControllerTest;
77   FRIEND_TEST_ALL_PREFIXES(TouchCalibratorControllerTest, TouchThreshold);
78   FRIEND_TEST_ALL_PREFIXES(TouchCalibratorControllerTest, CustomCalibration);
79   FRIEND_TEST_ALL_PREFIXES(TouchCalibratorControllerTest,
80                            CustomCalibrationInvalidTouchId);
81   FRIEND_TEST_ALL_PREFIXES(TouchCalibratorControllerTest,
82                            InternalTouchDeviceIsRejected);
83 
84   enum class CalibrationState {
85     // Indicates that the touch calibration is currently active with the built
86     // in native UX.
87     kNativeCalibration = 0,
88 
89     // Indicates that the touch calibration is currently active with a custom
90     // UX via the extensions API.
91     kCustomCalibration,
92 
93     // Indicates that touch calibration is currently inactive.
94     kInactive
95   };
96 
97   CalibrationState state_ = CalibrationState::kInactive;
98 
99   // A map for TouchCalibrator view with the key as display id of the display
100   // it is present in.
101   std::map<int64_t, views::UniqueWidgetPtr> touch_calibrator_widgets_;
102 
103   // The display which is being calibrated by the touch calibrator controller.
104   // This is valid only if |is_calibrating| is set to true.
105   display::Display target_display_;
106 
107   // During calibration this stores the timestamp when the previous touch event
108   // was received.
109   base::Time last_touch_timestamp_;
110 
111   // This is populated during calibration, based on the source id of the device
112   // the events are originating from.
113   int touch_device_id_ = ui::InputDevice::kInvalidId;
114 
115   // A set of ids that belong to touch devices associated with the internal
116   // display and are of type |ui::InputDeviceType::INPUT_DEVICE_INTERNAL|. This
117   // is only valid when |state_| is not |kInactive|.
118   std::set<int> internal_touch_device_ids_;
119 
120   // An array of Calibration point pairs. This stores all the 4 display and
121   // touch input point pairs that will be used for calibration.
122   CalibrationPointPairQuad touch_point_quad_;
123 
124   // A callback to be called when touch calibration completes.
125   TouchCalibrationCallback opt_callback_;
126 
127   // The touch device under calibration may be re-associated to another display
128   // during calibration. In such a case, the events originating from the touch
129   // device are tranformed based on parameters of the previous display it was
130   // linked to. We need to undo these transformations before recording the event
131   // locations.
132   gfx::Transform event_transformer_;
133 
134   DISALLOW_COPY_AND_ASSIGN(TouchCalibratorController);
135 };
136 
137 }  // namespace ash
138 #endif  // ASH_DISPLAY_TOUCH_CALIBRATOR_TOUCH_CALIBRATOR_CONTROLLER_H_
139