0

Enable mouse support in Starboard.

This is needed for things like touch input and linux.

Test: Manual and update UT
Bug: 397845560
Change-Id: I9378f0e665d05a741b37fc7bca98866678d1446d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6310945
Reviewed-by: Antonio Rivera <antoniori@google.com>
Commit-Queue: Shawn Quereshi <shawnq@google.com>
Cr-Commit-Position: refs/heads/main@{#1425981}
This commit is contained in:
Shawn Quereshi
2025-02-27 14:20:08 -08:00
committed by Chromium LUCI CQ
parent 6f5278dbe2
commit 97fcbdbab1
2 changed files with 81 additions and 12 deletions
chromecast/starboard/chromecast/events

@ -87,14 +87,17 @@ void StarboardEventSource::SbEventHandleInternal(const SbEvent* event) {
SbTimeMonotonic raw_timestamp = event->timestamp;
SbInputEventType raw_type = input_data->type;
SbKey raw_key = input_data->key;
SbInputVector raw_position = input_data->position;
if (raw_type != kSbInputEventTypePress &&
raw_type != kSbInputEventTypeUnpress) {
raw_type != kSbInputEventTypeUnpress &&
raw_type != kSbInputEventTypeMove) {
return;
}
// Find out if the press is supported by Cast.
auto it = kSbKeyToDomCodeMap.find(raw_key);
if (it == kSbKeyToDomCodeMap.end()) {
if (it == kSbKeyToDomCodeMap.end() && raw_key != kSbKeyMouse1 &&
raw_type != kSbInputEventTypeMove) {
return;
}
@ -103,19 +106,36 @@ void StarboardEventSource::SbEventHandleInternal(const SbEvent* event) {
ui::KeyboardCode key_code;
ui::DomCode dom_code = it->second;
int flags = 0;
if (!DomCodeToUsLayoutDomKey(dom_code, flags, &dom_key, &key_code)) {
if (DomCodeToUsLayoutDomKey(dom_code, flags, &dom_key, &key_code)) {
// Key press.
ui::EventType event_type = raw_type == kSbInputEventTypePress
? ui::EventType::kKeyPressed
: ui::EventType::kKeyReleased;
ui_event = std::make_unique<ui::KeyEvent>(
event_type, key_code, dom_code, flags, dom_key,
/*time_stamp=*/base::TimeTicks() + base::Microseconds(raw_timestamp));
} else if (raw_key == kSbKeyMouse1) {
// Mouse left click.
ui::EventType event_type = raw_type == kSbInputEventTypePress
? ui::EventType::kMousePressed
: ui::EventType::kMouseReleased;
ui_event = std::make_unique<ui::MouseEvent>(
event_type, gfx::PointF(raw_position.x, raw_position.y),
gfx::PointF(raw_position.x, raw_position.y),
base::TimeTicks() + base::Microseconds(raw_timestamp),
ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
} else if (raw_type == kSbInputEventTypeMove) {
// Mouse move.
ui::EventType event_type = ui::EventType::kMouseMoved;
ui_event = std::make_unique<ui::MouseEvent>(
event_type, gfx::PointF(raw_position.x, raw_position.y),
gfx::PointF(raw_position.x, raw_position.y),
base::TimeTicks() + base::Microseconds(raw_timestamp), flags, flags);
} else {
// Unsupported by Cast.
return;
}
// Key press.
ui::EventType event_type = raw_type == kSbInputEventTypePress
? ui::EventType::kKeyPressed
: ui::EventType::kKeyReleased;
ui_event = std::make_unique<ui::KeyEvent>(
event_type, key_code, dom_code, flags, dom_key,
/*time_stamp=*/
base::TimeTicks() + base::Microseconds(raw_timestamp));
ui::Event::Properties properties;
properties[chromecast::kPropertyFromStarboard] =
std::vector<uint8_t>(chromecast::kPropertyFromStarboardSize);

@ -92,6 +92,8 @@ using ::testing::_;
constexpr float kXPosClick = 1;
constexpr float kYPosClick = 2;
constexpr float kXPosMove = 3;
constexpr float kYPosMove = 4;
void DispatchSbEvent(const SbEvent* event) {
// The |source_| should be subscribed to this and receive the event.
@ -114,6 +116,19 @@ void EmulateKey(SbKey key, bool press) {
DispatchSbEvent(&event);
}
void EmulateMove() {
SbInputData input_data;
input_data.type = kSbInputEventTypeMove;
input_data.position.x = kXPosMove;
input_data.position.y = kYPosMove;
SbEvent event;
event.type = kSbEventTypeInput;
event.data = &input_data;
DispatchSbEvent(&event);
}
// A test fixture is used to manage the global mock state and to handle the
// lifetime of the SingleThreadTaskEnvironment.
class StarboardEventSourceTest : public ::testing::Test {
@ -163,5 +178,39 @@ TEST_F(StarboardEventSourceTest, UnsupportedClickIsNotPropagated) {
EXPECT_EQ(last_ui_event_, nullptr);
}
TEST_F(StarboardEventSourceTest, Move) {
EmulateMove();
ASSERT_NE(last_ui_event_, nullptr);
EXPECT_TRUE(last_ui_event_->IsMouseEvent());
EXPECT_EQ(last_ui_event_->type(), ui::EventType::kMouseMoved);
EXPECT_EQ(last_ui_event_->AsLocatedEvent()->location().x(), kXPosMove);
EXPECT_EQ(last_ui_event_->AsLocatedEvent()->location().y(), kYPosMove);
}
TEST_F(StarboardEventSourceTest, SupportedClick) {
EmulateKey(kSbKeyMouse1, true);
ASSERT_NE(last_ui_event_, nullptr);
EXPECT_TRUE(last_ui_event_->IsMouseEvent());
EXPECT_EQ(last_ui_event_->type(), ui::EventType::kMousePressed);
EXPECT_EQ(last_ui_event_->AsLocatedEvent()->location().x(), kXPosClick);
EXPECT_EQ(last_ui_event_->AsLocatedEvent()->location().y(), kYPosClick);
EXPECT_TRUE(last_ui_event_->AsMouseEvent()->IsOnlyLeftMouseButton());
EmulateKey(kSbKeyMouse1, false);
EXPECT_TRUE(last_ui_event_->IsMouseEvent());
EXPECT_EQ(ui::EventType::kMouseReleased, last_ui_event_->type());
EXPECT_EQ(kXPosClick, last_ui_event_->AsLocatedEvent()->location().x());
EXPECT_EQ(kYPosClick, last_ui_event_->AsLocatedEvent()->location().y());
EXPECT_TRUE(last_ui_event_->AsMouseEvent()->IsOnlyLeftMouseButton());
}
TEST_F(StarboardEventSourceTest, UnsupportedClick) {
EmulateKey(kSbKeyMouse2, true);
EXPECT_EQ(last_ui_event_, nullptr);
EmulateKey(kSbKeyMouse2, false);
EXPECT_EQ(last_ui_event_, nullptr);
}
} // namespace
} // namespace chromecast