blob: 745419d9c3b5a296abbc16562602fa18fb655122 [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/ui/scenic/lib/input/touch_injector.h"
#include <lib/syslog/cpp/macros.h>
namespace scenic_impl::input {
using InjectorEventPhase = fuchsia::ui::pointerinjector::EventPhase;
namespace {
InternalTouchEvent CreateCancelEvent(uint32_t device_id, uint32_t pointer_id, zx_koid_t context,
zx_koid_t target) {
InternalTouchEvent cancel_event;
cancel_event.phase = Phase::kCancel;
cancel_event.device_id = device_id;
cancel_event.pointer_id = pointer_id;
cancel_event.context = context;
cancel_event.target = target;
return cancel_event;
}
} // namespace
TouchInjector::TouchInjector(inspect::Node inspect_node, InjectorSettings settings,
Viewport viewport,
fidl::InterfaceRequest<fuchsia::ui::pointerinjector::Device> device,
fit::function<bool(/*descendant*/ zx_koid_t, /*ancestor*/ zx_koid_t)>
is_descendant_and_connected,
fit::function<void(const InternalTouchEvent&, StreamId)> inject,
fit::function<void()> on_channel_closed)
: Injector(std::move(inspect_node), settings, std::move(viewport), std::move(device),
std::move(is_descendant_and_connected), std::move(on_channel_closed)),
inject_(std::move(inject)) {
FX_DCHECK(inject_);
FX_DCHECK(settings.device_type == fuchsia::ui::pointerinjector::DeviceType::TOUCH);
}
void TouchInjector::ForwardEvent(const fuchsia::ui::pointerinjector::Event& event,
StreamId stream_id) {
FX_DCHECK(stream_id != kInvalidStreamId);
inject_(PointerInjectorEventToInternalTouchEvent(event), stream_id);
}
InternalTouchEvent TouchInjector::PointerInjectorEventToInternalTouchEvent(
const fuchsia::ui::pointerinjector::Event& event) const {
const InjectorSettings& settings = Injector::settings();
InternalTouchEvent internal_event;
internal_event.timestamp = event.timestamp();
internal_event.device_id = settings.device_id;
const fuchsia::ui::pointerinjector::PointerSample& pointer_sample = event.data().pointer_sample();
internal_event.pointer_id = pointer_sample.pointer_id();
internal_event.viewport = viewport();
internal_event.position_in_viewport = {pointer_sample.position_in_viewport()[0],
pointer_sample.position_in_viewport()[1]};
internal_event.context = settings.context_koid;
internal_event.target = settings.target_koid;
switch (pointer_sample.phase()) {
case InjectorEventPhase::ADD: {
internal_event.phase = Phase::kAdd;
break;
}
case InjectorEventPhase::CHANGE: {
internal_event.phase = Phase::kChange;
break;
}
case InjectorEventPhase::REMOVE: {
internal_event.phase = Phase::kRemove;
break;
}
case InjectorEventPhase::CANCEL: {
internal_event.phase = Phase::kCancel;
break;
}
default: {
FX_CHECK(false) << "unsupported phase: " << static_cast<uint32_t>(pointer_sample.phase());
break;
}
}
return internal_event;
}
void TouchInjector::CancelStream(uint32_t pointer_id, StreamId stream_id) {
const InjectorSettings& settings = Injector::settings();
inject_(CreateCancelEvent(settings.device_id, pointer_id, settings.context_koid,
settings.target_koid),
stream_id);
}
} // namespace scenic_impl::input