Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
KeyData.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.android;
6
7import androidx.annotation.NonNull;
8import androidx.annotation.Nullable;
9import java.io.UnsupportedEncodingException;
10import java.nio.ByteBuffer;
11import java.nio.ByteOrder;
12
13/**
14 * The resulting Flutter key events generated by {@link KeyEmbedderResponder}, and are sent through
15 * the messenger after being marshalled with {@link #toBytes()}.
16 *
17 * <p>This class is the Java adaption of {@code KeyData} and {@code KeyDataPacket} in the C engine.
18 * Changes made to either side must also be made to the other.
19 *
20 * <p>Each {@link KeyData} corresponds to a {@code ui.KeyData} in the framework.
21 */
22public class KeyData {
23 private static final String TAG = "KeyData";
24
25 /**
26 * The channel that key data should be sent through.
27 *
28 * <p>Must be kept in sync with kFlutterKeyDataChannel in embedder.cc
29 */
30 public static final String CHANNEL = "flutter/keydata";
31
32 // The number of fields except for `character`.
33 // If this value changes, update the code in the following files:
34 //
35 // * key_data.h (kKeyDataFieldCount)
36 // * platform_dispatcher.dart (_kKeyDataFieldCount)
37 private static final int FIELD_COUNT = 6;
38 private static final int BYTES_PER_FIELD = 8;
39
40 /** The action type of the key data. */
41 public enum Type {
43 kUp(1),
45
46 private long value;
47
48 private Type(long value) {
49 this.value = value;
50 }
51
52 public long getValue() {
53 return value;
54 }
55
56 static Type fromLong(long value) {
57 switch ((int) value) {
58 case 0:
59 return kDown;
60 case 1:
61 return kUp;
62 case 2:
63 return kRepeat;
64 default:
65 throw new AssertionError("Unexpected Type value");
66 }
67 }
68 }
69
70 /** The device type of the key data. */
71 public enum DeviceType {
77
78 private final long value;
79
80 private DeviceType(long value) {
81 this.value = value;
82 }
83
84 public long getValue() {
85 return value;
86 }
87
88 static DeviceType fromLong(long value) {
89 switch ((int) value) {
90 case 0:
91 return kKeyboard;
92 case 1:
93 return kDirectionalPad;
94 case 2:
95 return kGamepad;
96 case 3:
97 return kJoystick;
98 case 4:
99 return kHdmi;
100 default:
101 throw new AssertionError("Unexpected DeviceType value");
102 }
103 }
104 }
105
106 /** Creates an empty {@link KeyData}. */
107 public KeyData() {}
108
109 /**
110 * Unmarshal fields from a buffer.
111 *
112 * <p>For the binary format, see {@code lib/ui/window/key_data_packet.h}.
113 */
114 public KeyData(@NonNull ByteBuffer buffer) {
115 final long charSize = buffer.getLong();
116 this.timestamp = buffer.getLong();
117 this.type = Type.fromLong(buffer.getLong());
118 this.physicalKey = buffer.getLong();
119 this.logicalKey = buffer.getLong();
120 this.synthesized = buffer.getLong() != 0;
121 this.deviceType = DeviceType.fromLong(buffer.getLong());
122
123 if (buffer.remaining() != charSize) {
124 throw new AssertionError(
125 String.format(
126 "Unexpected char length: charSize is %d while buffer has position %d, capacity %d, limit %d",
127 charSize, buffer.position(), buffer.capacity(), buffer.limit()));
128 }
129 this.character = null;
130 if (charSize != 0) {
131 final byte[] strBytes = new byte[(int) charSize];
132 buffer.get(strBytes, 0, (int) charSize);
133 try {
134 this.character = new String(strBytes, "UTF-8");
135 } catch (UnsupportedEncodingException e) {
136 throw new AssertionError("UTF-8 unsupported");
137 }
138 }
139 }
140
145 boolean synthesized;
147
148 /** The character of this key data encoded in UTF-8. */
149 @Nullable String character;
150
151 /**
152 * Marshal the key data to a new byte buffer.
153 *
154 * <p>For the binary format, see {@code lib/ui/window/key_data_packet.h}.
155 *
156 * @return the marshalled bytes.
157 */
158 ByteBuffer toBytes() {
159 byte[] charBytes;
160 try {
161 charBytes = character == null ? null : character.getBytes("UTF-8");
162 } catch (UnsupportedEncodingException e) {
163 throw new AssertionError("UTF-8 not supported");
164 }
165 final int charSize = charBytes == null ? 0 : charBytes.length;
166 final ByteBuffer packet =
167 ByteBuffer.allocateDirect((1 + FIELD_COUNT) * BYTES_PER_FIELD + charSize);
168 packet.order(ByteOrder.LITTLE_ENDIAN);
169
170 packet.putLong(charSize);
171 packet.putLong(timestamp);
172 packet.putLong(type.getValue());
173 packet.putLong(physicalKey);
174 packet.putLong(logicalKey);
175 packet.putLong(synthesized ? 1L : 0L);
176 packet.putLong(deviceType.getValue());
177 if (charBytes != null) {
178 packet.put(charBytes);
179 }
180
181 return packet;
182 }
183}
Type::kYUV Type::kRGBA() int(0.7 *637)
KeyData(@NonNull ByteBuffer buffer)
Definition KeyData.java:114
@ kUp
Definition embedder.h:971
@ kDown
Definition embedder.h:978
static DeviceType fromLong(long value)
Definition KeyData.java:88
static const uint8_t buffer[]
uint8_t value