• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
5 package io.flutter.embedding.engine.systemchannels;
6 
7 import android.os.Build;
8 import android.support.annotation.NonNull;
9 import android.support.annotation.Nullable;
10 import android.view.InputDevice;
11 import android.view.KeyEvent;
12 
13 import java.util.HashMap;
14 import java.util.Map;
15 
16 import io.flutter.embedding.engine.dart.DartExecutor;
17 import io.flutter.plugin.common.BasicMessageChannel;
18 import io.flutter.plugin.common.JSONMessageCodec;
19 
20 /**
21  * TODO(mattcarroll): fill in javadoc for KeyEventChannel.
22  */
23 public class KeyEventChannel {
24 
25   @NonNull
26   public final BasicMessageChannel<Object> channel;
27 
KeyEventChannel(@onNull DartExecutor dartExecutor)28   public KeyEventChannel(@NonNull DartExecutor dartExecutor) {
29     this.channel = new BasicMessageChannel<>(dartExecutor, "flutter/keyevent", JSONMessageCodec.INSTANCE);
30   }
31 
keyUp(@onNull FlutterKeyEvent keyEvent)32   public void keyUp(@NonNull FlutterKeyEvent keyEvent) {
33     Map<String, Object> message = new HashMap<>();
34     message.put("type", "keyup");
35     message.put("keymap", "android");
36     encodeKeyEvent(keyEvent, message);
37 
38     channel.send(message);
39   }
40 
keyDown(@onNull FlutterKeyEvent keyEvent)41   public void keyDown(@NonNull FlutterKeyEvent keyEvent) {
42     Map<String, Object> message = new HashMap<>();
43     message.put("type", "keydown");
44     message.put("keymap", "android");
45     encodeKeyEvent(keyEvent, message);
46 
47     channel.send(message);
48   }
49 
encodeKeyEvent(@onNull FlutterKeyEvent event, @NonNull Map<String, Object> message)50   private void encodeKeyEvent(@NonNull FlutterKeyEvent event, @NonNull Map<String, Object> message) {
51     message.put("flags", event.flags);
52     message.put("plainCodePoint", event.plainCodePoint);
53     message.put("codePoint", event.codePoint);
54     message.put("keyCode", event.keyCode);
55     message.put("scanCode", event.scanCode);
56     message.put("metaState", event.metaState);
57     if (event.complexCharacter != null) {
58       message.put("character", event.complexCharacter.toString());
59     }
60     message.put("source", event.source);
61     message.put("vendorId", event.vendorId);
62     message.put("productId", event.productId);
63   }
64 
65   /**
66    * Key event as defined by Flutter.
67    */
68   public static class FlutterKeyEvent {
69     public final int deviceId;
70     public final int flags;
71     public final int plainCodePoint;
72     public final int codePoint;
73     public final int keyCode;
74     @Nullable
75     public final Character complexCharacter;
76     public final int scanCode;
77     public final int metaState;
78     public final int source;
79     public final int vendorId;
80     public final int productId;
81 
FlutterKeyEvent( @onNull KeyEvent androidKeyEvent )82     public FlutterKeyEvent(
83         @NonNull KeyEvent androidKeyEvent
84     ) {
85       this(androidKeyEvent, null);
86     }
87 
FlutterKeyEvent( @onNull KeyEvent androidKeyEvent, @Nullable Character complexCharacter )88     public FlutterKeyEvent(
89         @NonNull KeyEvent androidKeyEvent,
90         @Nullable Character complexCharacter
91     ) {
92       this(
93           androidKeyEvent.getDeviceId(),
94           androidKeyEvent.getFlags(),
95           androidKeyEvent.getUnicodeChar(0x0),
96           androidKeyEvent.getUnicodeChar(),
97           androidKeyEvent.getKeyCode(),
98           complexCharacter,
99           androidKeyEvent.getScanCode(),
100           androidKeyEvent.getMetaState(),
101           androidKeyEvent.getSource()
102       );
103     }
104 
FlutterKeyEvent( int deviceId, int flags, int plainCodePoint, int codePoint, int keyCode, @Nullable Character complexCharacter, int scanCode, int metaState, int source )105     public FlutterKeyEvent(
106         int deviceId,
107         int flags,
108         int plainCodePoint,
109         int codePoint,
110         int keyCode,
111         @Nullable Character complexCharacter,
112         int scanCode,
113         int metaState,
114         int source
115     ) {
116       this.deviceId = deviceId;
117       this.flags = flags;
118       this.plainCodePoint = plainCodePoint;
119       this.codePoint = codePoint;
120       this.keyCode = keyCode;
121       this.complexCharacter = complexCharacter;
122       this.scanCode = scanCode;
123       this.metaState = metaState;
124       this.source = source;
125       InputDevice device = InputDevice.getDevice(deviceId);
126       if (device != null) {
127         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
128           this.vendorId = device.getVendorId();
129           this.productId = device.getProductId();
130         } else {
131           this.vendorId = 0;
132           this.productId = 0;
133         }
134       } else {
135         this.vendorId = 0;
136         this.productId = 0;
137       }
138     }
139   }
140 }
141