Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
KeyEventChannel.java
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
5package io.flutter.embedding.engine.systemchannels;
6
7import android.view.KeyEvent;
8import androidx.annotation.NonNull;
9import androidx.annotation.Nullable;
10import io.flutter.Log;
11import io.flutter.plugin.common.BasicMessageChannel;
12import io.flutter.plugin.common.BinaryMessenger;
13import io.flutter.plugin.common.JSONMessageCodec;
14import java.util.HashMap;
15import java.util.Map;
16import org.json.JSONException;
17import org.json.JSONObject;
18
19/**
20 * Event message channel for key events to/from the Flutter framework.
21 *
22 * <p>Sends key up/down events to the framework, and receives asynchronous messages from the
23 * framework about whether or not the key was handled.
24 */
25public class KeyEventChannel {
26 private static final String TAG = "KeyEventChannel";
27
28 /** A handler of incoming key handling messages. */
29 public interface EventResponseHandler {
30
31 /**
32 * Called whenever the framework responds that a given key event was handled or not handled by
33 * the framework.
34 *
35 * @param isEventHandled whether the framework decides to handle the event.
36 */
37 public void onFrameworkResponse(boolean isEventHandled);
38 }
39
40 /**
41 * A constructor that creates a KeyEventChannel with the default message handler.
42 *
43 * @param binaryMessenger the binary messenger used to send messages on this channel.
44 */
45 public KeyEventChannel(@NonNull BinaryMessenger binaryMessenger) {
46 this.channel =
47 new BasicMessageChannel<>(binaryMessenger, "flutter/keyevent", JSONMessageCodec.INSTANCE);
48 }
49
50 @NonNull public final BasicMessageChannel<Object> channel;
51
53 @NonNull FlutterKeyEvent keyEvent,
54 boolean isKeyUp,
55 @NonNull EventResponseHandler responseHandler) {
56 channel.send(encodeKeyEvent(keyEvent, isKeyUp), createReplyHandler(responseHandler));
57 }
58
59 private Map<String, Object> encodeKeyEvent(@NonNull FlutterKeyEvent keyEvent, boolean isKeyUp) {
60 Map<String, Object> message = new HashMap<>();
61 message.put("type", isKeyUp ? "keyup" : "keydown");
62 message.put("keymap", "android");
63 message.put("flags", keyEvent.event.getFlags());
64 message.put("plainCodePoint", keyEvent.event.getUnicodeChar(0x0));
65 message.put("codePoint", keyEvent.event.getUnicodeChar());
66 message.put("keyCode", keyEvent.event.getKeyCode());
67 message.put("scanCode", keyEvent.event.getScanCode());
68 message.put("metaState", keyEvent.event.getMetaState());
69 if (keyEvent.complexCharacter != null) {
70 message.put("character", keyEvent.complexCharacter.toString());
71 }
72 message.put("source", keyEvent.event.getSource());
73 message.put("deviceId", keyEvent.event.getDeviceId());
74 message.put("repeatCount", keyEvent.event.getRepeatCount());
75 return message;
76 }
77
78 /**
79 * Creates a reply handler for the given key event.
80 *
81 * @param responseHandler the completion handler to call when the framework responds.
82 */
83 private static BasicMessageChannel.Reply<Object> createReplyHandler(
84 @NonNull EventResponseHandler responseHandler) {
85 return message -> {
86 boolean isEventHandled = false;
87 try {
88 if (message != null) {
89 final JSONObject annotatedEvent = (JSONObject) message;
90 isEventHandled = annotatedEvent.getBoolean("handled");
91 }
92 } catch (JSONException e) {
93 Log.e(TAG, "Unable to unpack JSON message: " + e);
94 }
95 responseHandler.onFrameworkResponse(isEventHandled);
96 };
97 }
98
99 /** A key event as defined by Flutter. */
100 public static class FlutterKeyEvent {
101 /**
102 * The Android key event that this Flutter key event was created from.
103 *
104 * <p>This event is used to identify pending events when results are received from the
105 * framework.
106 */
107 public final KeyEvent event;
108 /**
109 * The character produced by this event, including any combining characters pressed before it.
110 */
111 @Nullable public final Character complexCharacter;
112
113 public FlutterKeyEvent(@NonNull KeyEvent androidKeyEvent) {
114 this(androidKeyEvent, null);
115 }
116
118 @NonNull KeyEvent androidKeyEvent, @Nullable Character complexCharacter) {
119 this.event = androidKeyEvent;
120 this.complexCharacter = complexCharacter;
121 }
122 }
123}
FlutterKeyEvent( @NonNull KeyEvent androidKeyEvent, @Nullable Character complexCharacter)
void sendFlutterKeyEvent( @NonNull FlutterKeyEvent keyEvent, boolean isKeyUp, @NonNull EventResponseHandler responseHandler)
KeyEventChannel(@NonNull BinaryMessenger binaryMessenger)
Win32Message message