55package io .flutter .embedding .engine .systemchannels ;
66
77import android .os .Build ;
8- import android .util .Log ;
98import android .view .InputDevice ;
109import android .view .KeyEvent ;
1110import androidx .annotation .NonNull ;
1211import androidx .annotation .Nullable ;
13- import io .flutter .embedding . engine . dart . DartExecutor ;
12+ import io .flutter .Log ;
1413import io .flutter .plugin .common .BasicMessageChannel ;
14+ import io .flutter .plugin .common .BinaryMessenger ;
1515import io .flutter .plugin .common .JSONMessageCodec ;
1616import java .util .HashMap ;
1717import java .util .Map ;
2626 */
2727public class KeyEventChannel {
2828 private static final String TAG = "KeyEventChannel" ;
29- private static long eventIdSerial = 0 ;
3029
3130 /**
3231 * Sets the event response handler to be used to receive key event response messages from the
@@ -47,7 +46,7 @@ public interface EventResponseHandler {
4746 * @param id the event id of the event to be marked as being handled by the framework. Must not
4847 * be null.
4948 */
50- public void onKeyEventHandled (@ NonNull long id );
49+ public void onKeyEventHandled (long id );
5150
5251 /**
5352 * Called whenever the framework responds that a given key event wasn't handled by the
@@ -56,56 +55,58 @@ public interface EventResponseHandler {
5655 * @param id the event id of the event to be marked as not being handled by the framework. Must
5756 * not be null.
5857 */
59- public void onKeyEventNotHandled (@ NonNull long id );
58+ public void onKeyEventNotHandled (long id );
6059 }
6160
62- private final BasicMessageChannel .MessageHandler <Object > messageHandler =
63- new BasicMessageChannel .MessageHandler <Object >() {
64- @ Override
65- public void onMessage (
66- @ Nullable Object message , @ NonNull BasicMessageChannel .Reply <Object > reply ) {
67- // If there is no handler to respond to this message then we don't
68- // need to parse it.
69- if (eventResponseHandler == null ) {
70- return ;
71- }
72-
73- try {
74- final JSONObject annotatedEvent = (JSONObject ) message ;
75- final String type = annotatedEvent .getString ("type" );
76- final JSONObject data = annotatedEvent .getJSONObject ("data" );
77-
78- switch (type ) {
79- case "keyHandled" :
80- eventResponseHandler .onKeyEventHandled (data .getLong ("eventId" ));
81- break ;
82- case "keyNotHandled" :
83- eventResponseHandler .onKeyEventNotHandled (data .getLong ("eventId" ));
84- break ;
85- }
86- } catch (JSONException e ) {
87- Log .e (TAG , "Unable to unpack JSON message: " + e );
88- } finally {
89- reply .reply (null );
90- }
91- }
92- };
61+ /**
62+ * A constructor that creates a KeyEventChannel with the default message handler.
63+ *
64+ * @param binaryMessenger the binary messenger used to send messages on this channel.
65+ */
66+ public KeyEventChannel (@ NonNull BinaryMessenger binaryMessenger ) {
67+ this .channel =
68+ new BasicMessageChannel <>(binaryMessenger , "flutter/keyevent" , JSONMessageCodec .INSTANCE );
69+ }
9370
94- @ NonNull public final BasicMessageChannel <Object > channel ;
71+ /**
72+ * Creates a reply handler for this an event with the given eventId.
73+ *
74+ * @param eventId the event ID to create a reply for.
75+ */
76+ BasicMessageChannel .Reply <Object > createReplyHandler (long eventId ) {
77+ return message -> {
78+ if (eventResponseHandler == null ) {
79+ return ;
80+ }
9581
96- public KeyEventChannel (@ NonNull DartExecutor dartExecutor ) {
97- this .channel =
98- new BasicMessageChannel <>(dartExecutor , "flutter/keyevent" , JSONMessageCodec .INSTANCE );
99- this .channel .setMessageHandler (messageHandler );
82+ try {
83+ if (message == null ) {
84+ eventResponseHandler .onKeyEventNotHandled (eventId );
85+ return ;
86+ }
87+ final JSONObject annotatedEvent = (JSONObject ) message ;
88+ final boolean handled = annotatedEvent .getBoolean ("handled" );
89+ if (handled ) {
90+ eventResponseHandler .onKeyEventHandled (eventId );
91+ } else {
92+ eventResponseHandler .onKeyEventNotHandled (eventId );
93+ }
94+ } catch (JSONException e ) {
95+ Log .e (TAG , "Unable to unpack JSON message: " + e );
96+ eventResponseHandler .onKeyEventNotHandled (eventId );
97+ }
98+ };
10099 }
101100
101+ @ NonNull public final BasicMessageChannel <Object > channel ;
102+
102103 public void keyUp (@ NonNull FlutterKeyEvent keyEvent ) {
103104 Map <String , Object > message = new HashMap <>();
104105 message .put ("type" , "keyup" );
105106 message .put ("keymap" , "android" );
106107 encodeKeyEvent (keyEvent , message );
107108
108- channel .send (message );
109+ channel .send (message , createReplyHandler ( keyEvent . eventId ) );
109110 }
110111
111112 public void keyDown (@ NonNull FlutterKeyEvent keyEvent ) {
@@ -114,7 +115,7 @@ public void keyDown(@NonNull FlutterKeyEvent keyEvent) {
114115 message .put ("keymap" , "android" );
115116 encodeKeyEvent (keyEvent , message );
116117
117- channel .send (message );
118+ channel .send (message , createReplyHandler ( keyEvent . eventId ) );
118119 }
119120
120121 private void encodeKeyEvent (
@@ -136,7 +137,10 @@ private void encodeKeyEvent(
136137 message .put ("eventId" , event .eventId );
137138 }
138139
139- /** Key event as defined by Flutter. */
140+ /**
141+ * A key event as defined by Flutter that includes an id for the specific event to be used when
142+ * responding to the event.
143+ */
140144 public static class FlutterKeyEvent {
141145 public final int deviceId ;
142146 public final int flags ;
@@ -152,12 +156,12 @@ public static class FlutterKeyEvent {
152156 public final int repeatCount ;
153157 public final long eventId ;
154158
155- public FlutterKeyEvent (@ NonNull KeyEvent androidKeyEvent ) {
156- this (androidKeyEvent , null );
159+ public FlutterKeyEvent (@ NonNull KeyEvent androidKeyEvent , long eventId ) {
160+ this (androidKeyEvent , null , eventId );
157161 }
158162
159163 public FlutterKeyEvent (
160- @ NonNull KeyEvent androidKeyEvent , @ Nullable Character complexCharacter ) {
164+ @ NonNull KeyEvent androidKeyEvent , @ Nullable Character complexCharacter , long eventId ) {
161165 this (
162166 androidKeyEvent .getDeviceId (),
163167 androidKeyEvent .getFlags (),
@@ -168,7 +172,8 @@ public FlutterKeyEvent(
168172 androidKeyEvent .getScanCode (),
169173 androidKeyEvent .getMetaState (),
170174 androidKeyEvent .getSource (),
171- androidKeyEvent .getRepeatCount ());
175+ androidKeyEvent .getRepeatCount (),
176+ eventId );
172177 }
173178
174179 public FlutterKeyEvent (
@@ -181,7 +186,8 @@ public FlutterKeyEvent(
181186 int scanCode ,
182187 int metaState ,
183188 int source ,
184- int repeatCount ) {
189+ int repeatCount ,
190+ long eventId ) {
185191 this .deviceId = deviceId ;
186192 this .flags = flags ;
187193 this .plainCodePoint = plainCodePoint ;
@@ -192,7 +198,7 @@ public FlutterKeyEvent(
192198 this .metaState = metaState ;
193199 this .source = source ;
194200 this .repeatCount = repeatCount ;
195- this .eventId = eventIdSerial ++ ;
201+ this .eventId = eventId ;
196202 InputDevice device = InputDevice .getDevice (deviceId );
197203 if (device != null ) {
198204 if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .KITKAT ) {
0 commit comments