Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
pointer_delegate.h
Go to the documentation of this file.
1// Copyright 2013 The Flutter 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 FLUTTER_SHELL_PLATFORM_FUCHSIA_FLUTTER_POINTER_DELEGATE_H_
6#define FLUTTER_SHELL_PLATFORM_FUCHSIA_FLUTTER_POINTER_DELEGATE_H_
7
8#include <fuchsia/ui/pointer/cpp/fidl.h>
9
10#include <array>
11#include <functional>
12#include <optional>
13#include <unordered_map>
14#include <unordered_set>
15#include <vector>
16
17#include "flutter/lib/ui/window/pointer_data.h"
18
19namespace flutter_runner {
20
21// Helper class for keying into a map.
22struct IxnHasher {
23 std::size_t operator()(
24 const fuchsia::ui::pointer::TouchInteractionId& ixn) const {
25 return std::hash<uint32_t>()(ixn.device_id) ^
26 std::hash<uint32_t>()(ixn.pointer_id) ^
27 std::hash<uint32_t>()(ixn.interaction_id);
28 }
29};
30
31// Channel processors for fuchsia.ui.pointer.TouchSource and MouseSource
32// protocols. It manages the channel state, collects touch and mouse events, and
33// surfaces them to PlatformView as flutter::PointerData events for further
34// processing and dispatch.
36 public:
37 PointerDelegate(fuchsia::ui::pointer::TouchSourceHandle touch_source,
38 fuchsia::ui::pointer::MouseSourceHandle mouse_source);
39
40 // This function collects Fuchsia's TouchPointerSample and MousePointerSample
41 // data and transforms them into flutter::PointerData structs. It then calls
42 // the supplied callback with a vector of flutter::PointerData, which (1) does
43 // last processing (applies metrics), and (2) packs these flutter::PointerData
44 // in a flutter::PointerDataPacket for transport to the Engine.
45 void WatchLoop(
46 std::function<void(std::vector<flutter::PointerData>)> callback);
47
48 private:
49 /***** TOUCH STATE *****/
50
51 // Channel for touch events from Scenic.
52 fuchsia::ui::pointer::TouchSourcePtr touch_source_;
53
54 // Receive touch events from Scenic. Must be copyable.
55 std::function<void(std::vector<fuchsia::ui::pointer::TouchEvent>)>
56 touch_responder_;
57
58 // Per-interaction buffer of touch events from Scenic. When an interaction
59 // starts with event.pointer_sample.phase == ADD, we allocate a buffer and
60 // store samples. When interaction ownership becomes
61 // event.interaction_result.status == GRANTED, we flush the buffer to client,
62 // delete the buffer, and all future events in this interaction are flushed
63 // direct to client. When interaction ownership becomes DENIED, we delete the
64 // buffer, and the client does not get any previous or future events in this
65 // interaction.
66 //
67 // There are three basic interaction forms that we need to handle, and the API
68 // guarantees we see only these three forms. S=sample, R(g)=result-granted,
69 // R(d)=result-denied, and + means packaged in the same table. Time flows from
70 // left to right. Samples start with ADD, and end in REMOVE or CANCEL. Each
71 // interaction receives just one ownership result.
72 // (1) Late grant. S S S R(g) S S S
73 // (1-a) Combo. S S S+R(g) S S S
74 // (2) Early grant. S+R(g) S S S S S
75 // (3) Late deny. S S S R(d)
76 // (3-a) Combo. S S S+R(d)
77 //
78 // This results in the following high-level algorithm to correctly deal with
79 // buffer allocation and deletion, and event flushing or event dropping based
80 // on ownership.
81 // if event.sample.phase == ADD && !event.result
82 // allocate buffer[event.sample.interaction]
83 // if buffer[event.sample.interaction]
84 // buffer[event.sample.interaction].push(event.sample)
85 // else
86 // flush_to_client(event.sample)
87 // if event.result
88 // if event.result == GRANTED
89 // flush_to_client(buffer[event.result.interaction])
90 // delete buffer[event.result.interaction]
91 std::unordered_map<fuchsia::ui::pointer::TouchInteractionId,
92 std::vector<flutter::PointerData>,
94 touch_buffer_;
95
96 // The fuchsia.ui.pointer.TouchSource protocol allows one in-flight
97 // hanging-get Watch() call to gather touch events, and the client is expected
98 // to respond with consumption intent on the following hanging-get Watch()
99 // call. Store responses here for the next call.
100 std::vector<fuchsia::ui::pointer::TouchResponse> touch_responses_;
101
102 // The fuchsia.ui.pointer.TouchSource protocol issues channel-global view
103 // parameters on connection and on change. Events must apply these view
104 // parameters to correctly map to logical view coordinates. The "nullopt"
105 // state represents the absence of view parameters, early in the protocol
106 // lifecycle.
107 std::optional<fuchsia::ui::pointer::ViewParameters> touch_view_parameters_;
108
109 /***** MOUSE STATE *****/
110
111 // Channel for mouse events from Scenic.
112 fuchsia::ui::pointer::MouseSourcePtr mouse_source_;
113
114 // Receive mouse events from Scenic. Must be copyable.
115 std::function<void(std::vector<fuchsia::ui::pointer::MouseEvent>)>
116 mouse_responder_;
117
118 // The set of mouse devices that are currently interacting with the UI.
119 // A mouse is considered flutter::PointerData::Change::kDown if any button is
120 // pressed. This set is used to correctly set the phase in
121 // flutter::PointerData.change, with this high-level algorithm:
122 // if !mouse_down[id] && !button then: change = kHover
123 // if !mouse_down[id] && button then: change = kDown; mouse_down.add(id)
124 // if mouse_down[id] && button then: change = kMove
125 // if mouse_down[id] && !button then: change = kUp; mouse_down.remove(id)
126 std::unordered_set</*mouse device ID*/ uint32_t> mouse_down_;
127
128 // For each mouse device, its device-specific information, such as mouse
129 // button priority order.
130 std::unordered_map</*mouse device ID*/ uint32_t,
131 fuchsia::ui::pointer::MouseDeviceInfo>
132 mouse_device_info_;
133
134 // The fuchsia.ui.pointer.MouseSource protocol issues channel-global view
135 // parameters on connection and on change. Events must apply these view
136 // parameters to correctly map to logical view coordinates. The "nullopt"
137 // state represents the absence of view parameters, early in the protocol
138 // lifecycle.
139 std::optional<fuchsia::ui::pointer::ViewParameters> mouse_view_parameters_;
140};
141
142} // namespace flutter_runner
143#endif // FLUTTER_SHELL_PLATFORM_FUCHSIA_FLUTTER_POINTER_DELEGATE_H_
void WatchLoop(std::function< void(std::vector< flutter::PointerData >)> callback)
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
std::size_t operator()(const fuchsia::ui::pointer::TouchInteractionId &ixn) const