6#include "flutter/fml/logging.h"
26 static constexpr std::array<float, 9> kIdentityMatrix = {
36 rapidjson::Value request,
38 if (!registry_->is_bound()) {
40 <<
"Lost connection to fuchsia.ui.pointerinjector.Registry";
44 auto method = request.FindMember(
"method");
45 if (method == request.MemberEnd() || !method->value.IsString()) {
46 FML_LOG(
ERROR) <<
"No method found in platform message.";
51 FML_LOG(
ERROR) <<
"Unexpected platform message method, expected "
52 "View.pointerinjector.inject.";
56 auto args_it = request.FindMember(
"args");
57 if (args_it == request.MemberEnd() || !args_it->value.IsObject()) {
58 FML_LOG(
ERROR) <<
"No arguments found in platform message's method";
62 const auto&
args = args_it->value;
64 auto view_id =
args.FindMember(
"viewId");
65 if (!view_id->value.IsUint64()) {
70 auto id = view_id->value.GetUint64();
71 if (valid_views_.count(
id) == 0) {
76 Complete(std::move(response),
"[0]");
80 auto phase =
args.FindMember(
"phase");
81 if (!phase->value.IsInt()) {
86 auto pointer_x =
args.FindMember(
"x");
87 if (!pointer_x->value.IsFloat() && !pointer_x->value.IsInt()) {
92 auto pointer_y =
args.FindMember(
"y");
93 if (!pointer_y->value.IsFloat() && !pointer_y->value.IsInt()) {
98 auto pointer_id =
args.FindMember(
"pointerId");
99 if (!pointer_id->value.IsUint()) {
100 FML_LOG(
ERROR) <<
"Argument 'pointerId' is not a uint32";
104 auto trace_flow_id =
args.FindMember(
"traceFlowId");
105 if (!trace_flow_id->value.IsInt()) {
106 FML_LOG(
ERROR) <<
"Argument 'traceFlowId' is not a int";
110 auto width =
args.FindMember(
"logicalWidth");
111 if (!
width->value.IsFloat() && !
width->value.IsInt()) {
112 FML_LOG(
ERROR) <<
"Argument 'logicalWidth' is not a float";
116 auto height =
args.FindMember(
"logicalHeight");
117 if (!
height->value.IsFloat() && !
height->value.IsInt()) {
118 FML_LOG(
ERROR) <<
"Argument 'logicalHeight' is not a float";
122 auto timestamp =
args.FindMember(
"timestamp");
123 if (!timestamp->value.IsInt() && !timestamp->value.IsUint64()) {
128 PointerInjectorRequest
event = {
129 .x = pointer_x->value.GetFloat(),
130 .y = pointer_y->value.GetFloat(),
131 .pointer_id = pointer_id->value.GetUint(),
133 .trace_flow_id = trace_flow_id->value.GetUint64(),
134 .logical_size = {
width->value.GetFloat(),
height->value.GetFloat()},
135 .timestamp = timestamp->value.GetInt()};
138 valid_views_.at(
id).InjectEvent(std::move(
event));
139 Complete(std::move(response),
"[0]");
145 std::optional<fuv_ViewRef> view_ref) {
146 FML_CHECK(valid_views_.count(view_id) == 0);
148 auto [_, success] = valid_views_.try_emplace(
149 view_id, registry_, host_view_ref_, std::move(view_ref));
154fup_Event PointerInjectorDelegate::ExtractPointerEvent(
155 PointerInjectorRequest request) {
157 event.set_timestamp(request.timestamp);
158 event.set_trace_flow_id(request.trace_flow_id);
161 pointer_sample.set_pointer_id(request.pointer_id);
162 pointer_sample.set_phase(request.phase);
163 pointer_sample.set_position_in_viewport({request.x, request.y});
166 data.set_pointer_sample(std::move(pointer_sample));
168 event.set_data(std::move(
data));
172void PointerInjectorDelegate::Complete(
176 response->
Complete(std::make_unique<fml::DataMapping>(
177 std::vector<uint8_t>(
value.begin(),
value.end())));
181void PointerInjectorDelegate::PointerInjectorEndpoint::InjectEvent(
182 PointerInjectorRequest request) {
184 RegisterInjector(request);
187 auto event = ExtractPointerEvent(std::move(request));
190 EnqueueEvent(std::move(
event));
192 DispatchPendingEvents();
195void PointerInjectorDelegate::PointerInjectorEndpoint::DispatchPendingEvents() {
199 if (injection_in_flight_) {
209 if (!injector_events_.empty()) {
210 auto events = std::move(injector_events_.front());
211 injector_events_.pop();
212 injection_in_flight_ =
true;
217 device_->Inject(std::move(events), [weak = weak_factory_.GetWeakPtr()] {
219 FML_LOG(WARNING) <<
"Use after free attempted.";
222 weak->injection_in_flight_ =
false;
223 weak->DispatchPendingEvents();
228void PointerInjectorDelegate::PointerInjectorEndpoint::EnqueueEvent(
232 if (!injector_events_.empty() &&
234 injector_events_.back().push_back(std::move(
event));
236 std::vector<fup_Event> vec;
238 vec.push_back(std::move(
event));
239 injector_events_.push(std::move(vec));
243void PointerInjectorDelegate::PointerInjectorEndpoint::RegisterInjector(
244 const PointerInjectorRequest& request) {
250 config.set_device_id(1);
251 config.set_device_type(fup_DeviceType::TOUCH);
252 config.set_dispatch_policy(fup_DispatchPolicy::EXCLUSIVE_TARGET);
256 fidl::Clone(*host_view_ref_, &context_clone);
257 context.set_view(std::move(context_clone));
258 config.set_context(std::move(context));
265 target.set_view(std::move(target_clone));
266 config.set_target(std::move(
target));
269 viewport.set_viewport_to_context_transform(kIdentityMatrix);
270 std::array<std::array<float, 2>, 2> extents{
272 {request.logical_size[0], request.logical_size[1]}}};
273 viewport.set_extents(std::move(extents));
274 config.set_viewport(std::move(viewport));
278 (*registry_)->Register(std::move(config), device_.NewRequest(), [] {});
284 injection_in_flight_ =
false;
286 injector_events_ = {};
GrAATriangulator::Event Event
bool HandlePlatformMessage(rapidjson::Value request, fml::RefPtr< flutter::PlatformMessageResponse > response)
static constexpr auto kPointerInjectorMethodPrefix
void OnCreateView(uint64_t view_id, std::optional< fuchsia::ui::views::ViewRef > view_ref=std::nullopt)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
#define FML_LOG(severity)
#define FML_CHECK(condition)
fuchsia::ui::pointerinjector::Event fup_Event
const auto fup_MAX_INJECT
fuchsia::ui::pointerinjector::Target fup_Target
fuchsia::ui::views::ViewRef fuv_ViewRef
fuchsia::ui::pointerinjector::DeviceType fup_DeviceType
fuchsia::ui::pointerinjector::Context fup_Context
fuchsia::ui::pointerinjector::DispatchPolicy fup_DispatchPolicy
fuchsia::ui::pointerinjector::Viewport fup_Viewport
fuchsia::ui::pointerinjector::Config fup_Config
fuchsia::ui::pointerinjector::PointerSample fup_PointerSample
fuchsia::ui::pointerinjector::Data fup_Data
fuchsia::ui::pointer::EventPhase fup_EventPhase
struct PathData * Data(SkPath *path)
std::shared_ptr< const fml::Mapping > data