diff --git a/packages/flutter/lib/src/services/raw_keyboard.dart b/packages/flutter/lib/src/services/raw_keyboard.dart index a38f415d649..2aa21a9feb1 100644 --- a/packages/flutter/lib/src/services/raw_keyboard.dart +++ b/packages/flutter/lib/src/services/raw_keyboard.dart @@ -59,6 +59,30 @@ class RawKeyEventDataAndroid extends RawKeyEventData { final int metaState; } +/// Platform-specific key event data for Fuchsia. +/// +/// This object contains information about key events obtained from Fuchsia's +/// KeyData interface. +class RawKeyEventDataFuchsia extends RawKeyEventData { + /// Creates a key event data structure specific for Android. + /// + /// The [hidUsage] and [codePoint] arguments must not be null. + const RawKeyEventDataFuchsia({ + this.hidUsage: 0, + this.codePoint: 0, + }); + + /// The USB HID usage. + /// + /// See + final int hidUsage; + + /// The unicode code point represented by the key event, if any. + /// + /// If there is no unicode code point, this value is zero. + final int codePoint; +} + /// Base class for raw key events. /// /// Raw key events pass through as much information as possible from the @@ -96,7 +120,7 @@ class RawKeyUpEvent extends RawKeyEvent { }) : super(data: data); } -RawKeyEvent _toRawKeyEvent(dynamic message) { +RawKeyEvent _toRawKeyEvent(Map message) { RawKeyEventData data; String keymap = message['keymap']; @@ -110,7 +134,15 @@ RawKeyEvent _toRawKeyEvent(dynamic message) { metaState: message['metaState'] ?? 0, ); break; + case 'fuchsia': + data = new RawKeyEventDataFuchsia( + hidUsage: message['hidUsage'] ?? 0, + codePoint: message['codePoint'] ?? 0, + ); + break; default: + // We don't yet implement raw key events on iOS, but we don't hit this + // exception because the engine never sends us these messages. throw new FlutterError('Unknown keymap for key events: $keymap'); } @@ -120,14 +152,15 @@ RawKeyEvent _toRawKeyEvent(dynamic message) { return new RawKeyDownEvent(data: data); case 'keyup': return new RawKeyUpEvent(data: data); + default: + throw new FlutterError('Unknown key event type: $type'); } - throw new FlutterError('Unknown key event type: $type'); } /// An interface for listening to raw key events. /// /// Raw key events pass through as much information as possible from the -/// underlying platform's key events, which makes they provide a high level of +/// underlying platform's key events, which makes them provide a high level of /// fidelity but a low level of portability. /// /// A [RawKeyboard] is useful for listening to raw key events and hardware diff --git a/packages/flutter/test/widgets/raw_keyboard_listener_test.dart b/packages/flutter/test/widgets/raw_keyboard_listener_test.dart index 92a58c95f0a..8774cf62487 100644 --- a/packages/flutter/test/widgets/raw_keyboard_listener_test.dart +++ b/packages/flutter/test/widgets/raw_keyboard_listener_test.dart @@ -2,12 +2,51 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:flutter_test/flutter_test.dart'; +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void sendFakeKeyEvent(Map data) { + String message = JSON.encode(data); + Uint8List encoded = UTF8.encoder.convert(message); + PlatformMessages.handlePlatformMessage( + 'flutter/keyevent', encoded.buffer.asByteData(), (_) {}); +} void main() { testWidgets('Can dispose without keyboard', (WidgetTester tester) async { await tester.pumpWidget(new RawKeyboardListener(child: new Container())); await tester.pumpWidget(new Container()); }); + + testWidgets('Fuchsia key event', (WidgetTester tester) async { + List events = []; + + await tester.pumpWidget(new RawKeyboardListener( + focused: true, + onKey: (RawKeyEvent event) { + events.add(event); + }, + child: new Container(), + )); + + sendFakeKeyEvent({ + 'type': 'keydown', + 'keymap': 'fuchsia', + 'hidUsage': 0x04, + 'codePoint': 0x64, + }); + + await tester.idle(); + + expect(events.length, 1); + expect(events[0].runtimeType, equals(RawKeyDownEvent)); + expect(events[0].data.runtimeType, equals(RawKeyEventDataFuchsia)); + RawKeyEventDataFuchsia typedData = events[0].data; + expect(typedData.hidUsage, 0x04); + expect(typedData.codePoint, 0x64); + }); }