uinput: move Event.Reader to its own file
We'll shortly be adding a parser for a different file format (evemu),
and having the different parsers in separate files will make the code
nicer to navigate.
In addition to moving it to a separate file, this CL renames Reader to
JsonStyleParser to avoid confusion with Java's Reader classes, and
replaces some switch statements with the new-style switch syntax to
improve readability.
Bug: 302297266
Test: atest CtsInputHostTestCases
Change-Id: Id6c7536a2caea3b61fac615dce071129bf4dc1e4
diff --git a/cmds/uinput/src/com/android/commands/uinput/Event.java b/cmds/uinput/src/com/android/commands/uinput/Event.java
index 9d8f1f4..02269f8 100644
--- a/cmds/uinput/src/com/android/commands/uinput/Event.java
+++ b/cmds/uinput/src/com/android/commands/uinput/Event.java
@@ -16,19 +16,10 @@
package com.android.commands.uinput;
-import android.util.JsonReader;
-import android.util.JsonToken;
-import android.util.Log;
import android.util.SparseArray;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
import java.util.Arrays;
-import java.util.List;
import java.util.Objects;
-import java.util.function.Function;
-import java.util.stream.IntStream;
import src.com.android.commands.uinput.InputAbsInfo;
@@ -52,16 +43,18 @@
}
}
- private static final int EV_KEY = 0x01;
- private static final int EV_REL = 0x02;
- private static final int EV_ABS = 0x03;
- private static final int EV_MSC = 0x04;
- private static final int EV_SW = 0x05;
- private static final int EV_LED = 0x11;
- private static final int EV_SND = 0x12;
- private static final int EV_FF = 0x15;
+ // Constants representing evdev event types, from include/uapi/linux/input-event-codes.h in the
+ // kernel.
+ public static final int EV_KEY = 0x01;
+ public static final int EV_REL = 0x02;
+ public static final int EV_ABS = 0x03;
+ public static final int EV_MSC = 0x04;
+ public static final int EV_SW = 0x05;
+ public static final int EV_LED = 0x11;
+ public static final int EV_SND = 0x12;
+ public static final int EV_FF = 0x15;
- private enum UinputControlCode {
+ public enum UinputControlCode {
UI_SET_EVBIT("UI_SET_EVBIT", 100),
UI_SET_KEYBIT("UI_SET_KEYBIT", 101),
UI_SET_RELBIT("UI_SET_RELBIT", 102),
@@ -73,13 +66,21 @@
UI_SET_SWBIT("UI_SET_SWBIT", 109),
UI_SET_PROPBIT("UI_SET_PROPBIT", 110);
- final String mName;
- final int mValue;
+ private final String mName;
+ private final int mValue;
UinputControlCode(String name, int value) {
this.mName = name;
this.mValue = value;
}
+
+ public String getName() {
+ return mName;
+ }
+
+ public int getValue() {
+ return mValue;
+ }
}
// These constants come from "include/uapi/linux/input.h" in the kernel
@@ -180,7 +181,7 @@
+ "}";
}
- private static class Builder {
+ public static class Builder {
private Event mEvent;
Builder() {
@@ -191,7 +192,7 @@
mEvent.mId = id;
}
- private void setCommand(String command) {
+ public void setCommand(String command) {
Objects.requireNonNull(command, "Command must not be null");
for (Command cmd : Command.values()) {
if (cmd.mCommandName.equals(command)) {
@@ -278,343 +279,4 @@
return mEvent;
}
}
-
- /**
- * A class that parses the JSON event format from an input stream to build device events.
- */
- public static class Reader {
- private JsonReader mReader;
-
- public Reader(InputStreamReader in) {
- mReader = new JsonReader(in);
- mReader.setLenient(true);
- }
-
- /**
- * Get next event entry from JSON file reader.
- */
- public Event getNextEvent() throws IOException {
- Event e = null;
- while (e == null && mReader.peek() != JsonToken.END_DOCUMENT) {
- Event.Builder eb = new Event.Builder();
- try {
- mReader.beginObject();
- while (mReader.hasNext()) {
- String name = mReader.nextName();
- switch (name) {
- case "id":
- eb.setId(readInt());
- break;
- case "command":
- eb.setCommand(mReader.nextString());
- break;
- case "name":
- eb.setName(mReader.nextString());
- break;
- case "vid":
- eb.setVid(readInt());
- break;
- case "pid":
- eb.setPid(readInt());
- break;
- case "bus":
- eb.setBus(readBus());
- break;
- case "events":
- int[] injections = readInjectedEvents().stream()
- .mapToInt(Integer::intValue).toArray();
- eb.setInjections(injections);
- break;
- case "configuration":
- eb.setConfiguration(readConfiguration());
- break;
- case "ff_effects_max":
- eb.setFfEffectsMax(readInt());
- break;
- case "abs_info":
- eb.setAbsInfo(readAbsInfoArray());
- break;
- case "duration":
- eb.setDuration(readInt());
- break;
- case "port":
- eb.setInputport(mReader.nextString());
- break;
- case "syncToken":
- eb.setSyncToken(mReader.nextString());
- break;
- default:
- mReader.skipValue();
- }
- }
- mReader.endObject();
- } catch (IllegalStateException ex) {
- error("Error reading in object, ignoring.", ex);
- consumeRemainingElements();
- mReader.endObject();
- continue;
- }
- e = eb.build();
- }
-
- return e;
- }
-
- private ArrayList<Integer> readInjectedEvents() throws IOException {
- ArrayList<Integer> data = new ArrayList<>();
- try {
- mReader.beginArray();
- while (mReader.hasNext()) {
- // Read events in groups of three, because we expect an event type, event code,
- // and event value.
- final int type = readEvdevEventType();
- data.add(type);
- data.add(readEvdevEventCode(type));
- data.add(readInt());
- }
- mReader.endArray();
- } catch (IllegalStateException | NumberFormatException e) {
- consumeRemainingElements();
- mReader.endArray();
- throw new IllegalStateException("Encountered malformed data.", e);
- }
- return data;
- }
-
- private int readValueAsInt(Function<String, Integer> stringToInt) throws IOException {
- switch (mReader.peek()) {
- case NUMBER: {
- return mReader.nextInt();
- }
- case STRING: {
- final var str = mReader.nextString();
- try {
- // Attempt to first parse the value as an int.
- return Integer.decode(str);
- } catch (NumberFormatException e) {
- // Then fall back to the supplied function.
- return stringToInt.apply(str);
- }
- }
- default: {
- throw new IllegalStateException(
- "Encountered malformed data. Expected int or string.");
- }
- }
- }
-
- private int readInt() throws IOException {
- return readValueAsInt((str) -> {
- throw new IllegalStateException("Encountered malformed data. Expected int.");
- });
- }
-
- private Bus readBus() throws IOException {
- String val = mReader.nextString();
- return Bus.valueOf(val.toUpperCase());
- }
-
- private SparseArray<int[]> readConfiguration()
- throws IllegalStateException, IOException {
- SparseArray<int[]> configuration = new SparseArray<>();
- try {
- mReader.beginArray();
- while (mReader.hasNext()) {
- UinputControlCode controlCode = null;
- IntStream data = null;
- mReader.beginObject();
- while (mReader.hasNext()) {
- String name = mReader.nextName();
- switch (name) {
- case "type":
- controlCode = readUinputControlCode();
- break;
- case "data":
- Objects.requireNonNull(controlCode,
- "Configuration 'type' must be specified before 'data'.");
- data = readDataForControlCode(controlCode)
- .stream().mapToInt(Integer::intValue);
- break;
- default:
- consumeRemainingElements();
- mReader.endObject();
- throw new IllegalStateException(
- "Invalid key in device configuration: " + name);
- }
- }
- mReader.endObject();
- if (controlCode != null && data != null) {
- final int[] existing = configuration.get(controlCode.mValue);
- configuration.put(controlCode.mValue, existing == null ? data.toArray()
- : IntStream.concat(IntStream.of(existing), data).toArray());
- }
- }
- mReader.endArray();
- } catch (IllegalStateException | NumberFormatException e) {
- consumeRemainingElements();
- mReader.endArray();
- throw new IllegalStateException("Encountered malformed data.", e);
- }
- return configuration;
- }
-
- private UinputControlCode readUinputControlCode() throws IOException {
- var code = readValueAsInt((controlTypeStr) -> {
- for (UinputControlCode controlCode : UinputControlCode.values()) {
- if (controlCode.mName.equals(controlTypeStr)) {
- return controlCode.mValue;
- }
- }
- return -1;
- });
- for (UinputControlCode controlCode : UinputControlCode.values()) {
- if (controlCode.mValue == code) {
- return controlCode;
- }
- }
- return null;
- }
-
- private List<Integer> readDataForControlCode(
- UinputControlCode controlCode) throws IOException {
- return switch (controlCode) {
- case UI_SET_EVBIT -> readArrayAsInts(this::readEvdevEventType);
- case UI_SET_KEYBIT -> readArrayAsInts(() -> readEvdevEventCode(EV_KEY));
- case UI_SET_RELBIT -> readArrayAsInts(() -> readEvdevEventCode(EV_REL));
- case UI_SET_ABSBIT -> readArrayAsInts(() -> readEvdevEventCode(EV_ABS));
- case UI_SET_MSCBIT -> readArrayAsInts(() -> readEvdevEventCode(EV_MSC));
- case UI_SET_LEDBIT -> readArrayAsInts(() -> readEvdevEventCode(EV_LED));
- case UI_SET_SNDBIT -> readArrayAsInts(() -> readEvdevEventCode(EV_SND));
- case UI_SET_FFBIT -> readArrayAsInts(() -> readEvdevEventCode(EV_FF));
- case UI_SET_SWBIT -> readArrayAsInts(() -> readEvdevEventCode(EV_SW));
- case UI_SET_PROPBIT -> readArrayAsInts(this::readEvdevInputProp);
- };
- }
-
- interface IntValueReader {
- int readNextValue() throws IOException;
- }
-
- private ArrayList<Integer> readArrayAsInts(
- IntValueReader nextValueReader) throws IOException {
- ArrayList<Integer> data = new ArrayList<>();
- try {
- mReader.beginArray();
- while (mReader.hasNext()) {
- data.add(nextValueReader.readNextValue());
- }
- mReader.endArray();
- } catch (IllegalStateException | NumberFormatException e) {
- consumeRemainingElements();
- mReader.endArray();
- throw new IllegalStateException("Encountered malformed data.", e);
- }
- return data;
- }
-
- private InputAbsInfo readAbsInfo() throws IllegalStateException, IOException {
- InputAbsInfo absInfo = new InputAbsInfo();
- try {
- mReader.beginObject();
- while (mReader.hasNext()) {
- String name = mReader.nextName();
- switch (name) {
- case "value":
- absInfo.value = readInt();
- break;
- case "minimum":
- absInfo.minimum = readInt();
- break;
- case "maximum":
- absInfo.maximum = readInt();
- break;
- case "fuzz":
- absInfo.fuzz = readInt();
- break;
- case "flat":
- absInfo.flat = readInt();
- break;
- case "resolution":
- absInfo.resolution = readInt();
- break;
- default:
- consumeRemainingElements();
- mReader.endObject();
- throw new IllegalStateException("Invalid key in abs info: " + name);
- }
- }
- mReader.endObject();
- } catch (IllegalStateException | NumberFormatException e) {
- consumeRemainingElements();
- mReader.endObject();
- throw new IllegalStateException("Encountered malformed data.", e);
- }
- return absInfo;
- }
-
- private SparseArray<InputAbsInfo> readAbsInfoArray()
- throws IllegalStateException, IOException {
- SparseArray<InputAbsInfo> infoArray = new SparseArray<>();
- try {
- mReader.beginArray();
- while (mReader.hasNext()) {
- int type = 0;
- InputAbsInfo absInfo = null;
- mReader.beginObject();
- while (mReader.hasNext()) {
- String name = mReader.nextName();
- switch (name) {
- case "code":
- type = readEvdevEventCode(EV_ABS);
- break;
- case "info":
- absInfo = readAbsInfo();
- break;
- default:
- consumeRemainingElements();
- mReader.endObject();
- throw new IllegalStateException("Invalid key in abs info array: "
- + name);
- }
- }
- mReader.endObject();
- if (absInfo != null) {
- infoArray.put(type, absInfo);
- }
- }
- mReader.endArray();
- } catch (IllegalStateException | NumberFormatException e) {
- consumeRemainingElements();
- mReader.endArray();
- throw new IllegalStateException("Encountered malformed data.", e);
- }
- return infoArray;
- }
-
- private int readEvdevEventType() throws IOException {
- return readValueAsInt(Device::getEvdevEventTypeByLabel);
- }
-
- private int readEvdevEventCode(int type) throws IOException {
- return readValueAsInt((str) -> Device.getEvdevEventCodeByLabel(type, str));
- }
-
- private int readEvdevInputProp() throws IOException {
- return readValueAsInt(Device::getEvdevInputPropByLabel);
- }
-
- private void consumeRemainingElements() throws IOException {
- while (mReader.hasNext()) {
- mReader.skipValue();
- }
- }
- }
-
- private static void error(String msg, Exception e) {
- System.out.println(msg);
- Log.e(TAG, msg);
- if (e != null) {
- Log.e(TAG, Log.getStackTraceString(e));
- }
- }
}
diff --git a/cmds/uinput/src/com/android/commands/uinput/JsonStyleParser.java b/cmds/uinput/src/com/android/commands/uinput/JsonStyleParser.java
new file mode 100644
index 0000000..d8e0105
--- /dev/null
+++ b/cmds/uinput/src/com/android/commands/uinput/JsonStyleParser.java
@@ -0,0 +1,334 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.commands.uinput;
+
+import android.util.JsonReader;
+import android.util.JsonToken;
+import android.util.Log;
+import android.util.SparseArray;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Function;
+import java.util.stream.IntStream;
+
+import src.com.android.commands.uinput.InputAbsInfo;
+
+/**
+ * A class that parses the JSON-like event format described in the README to build {@link Event}s.
+ */
+public class JsonStyleParser {
+ private static final String TAG = "UinputJsonStyleParser";
+
+ private JsonReader mReader;
+
+ public JsonStyleParser(InputStreamReader in) {
+ mReader = new JsonReader(in);
+ mReader.setLenient(true);
+ }
+
+ /**
+ * Gets the next event entry from the JSON file.
+ */
+ public Event getNextEvent() throws IOException {
+ Event e = null;
+ while (e == null && mReader.peek() != JsonToken.END_DOCUMENT) {
+ Event.Builder eb = new Event.Builder();
+ try {
+ mReader.beginObject();
+ while (mReader.hasNext()) {
+ String name = mReader.nextName();
+ switch (name) {
+ case "id" -> eb.setId(readInt());
+ case "command" -> eb.setCommand(mReader.nextString());
+ case "name" -> eb.setName(mReader.nextString());
+ case "vid" -> eb.setVid(readInt());
+ case "pid" -> eb.setPid(readInt());
+ case "bus" -> eb.setBus(readBus());
+ case "events" -> {
+ int[] injections = readInjectedEvents().stream()
+ .mapToInt(Integer::intValue).toArray();
+ eb.setInjections(injections);
+ }
+ case "configuration" -> eb.setConfiguration(readConfiguration());
+ case "ff_effects_max" -> eb.setFfEffectsMax(readInt());
+ case "abs_info" -> eb.setAbsInfo(readAbsInfoArray());
+ case "duration" -> eb.setDuration(readInt());
+ case "port" -> eb.setInputport(mReader.nextString());
+ case "syncToken" -> eb.setSyncToken(mReader.nextString());
+ default -> mReader.skipValue();
+ }
+ }
+ mReader.endObject();
+ } catch (IllegalStateException ex) {
+ error("Error reading in object, ignoring.", ex);
+ consumeRemainingElements();
+ mReader.endObject();
+ continue;
+ }
+ e = eb.build();
+ }
+
+ return e;
+ }
+
+ private ArrayList<Integer> readInjectedEvents() throws IOException {
+ ArrayList<Integer> data = new ArrayList<>();
+ try {
+ mReader.beginArray();
+ while (mReader.hasNext()) {
+ // Read events in groups of three, because we expect an event type, event code,
+ // and event value.
+ final int type = readEvdevEventType();
+ data.add(type);
+ data.add(readEvdevEventCode(type));
+ data.add(readInt());
+ }
+ mReader.endArray();
+ } catch (IllegalStateException | NumberFormatException e) {
+ consumeRemainingElements();
+ mReader.endArray();
+ throw new IllegalStateException("Encountered malformed data.", e);
+ }
+ return data;
+ }
+
+ private int readValueAsInt(Function<String, Integer> stringToInt) throws IOException {
+ switch (mReader.peek()) {
+ case NUMBER: {
+ return mReader.nextInt();
+ }
+ case STRING: {
+ final var str = mReader.nextString();
+ try {
+ // Attempt to first parse the value as an int.
+ return Integer.decode(str);
+ } catch (NumberFormatException e) {
+ // Then fall back to the supplied function.
+ return stringToInt.apply(str);
+ }
+ }
+ default: {
+ throw new IllegalStateException(
+ "Encountered malformed data. Expected int or string.");
+ }
+ }
+ }
+
+ private int readInt() throws IOException {
+ return readValueAsInt((str) -> {
+ throw new IllegalStateException("Encountered malformed data. Expected int.");
+ });
+ }
+
+ private Event.Bus readBus() throws IOException {
+ String val = mReader.nextString();
+ return Event.Bus.valueOf(val.toUpperCase());
+ }
+
+ private SparseArray<int[]> readConfiguration()
+ throws IllegalStateException, IOException {
+ SparseArray<int[]> configuration = new SparseArray<>();
+ try {
+ mReader.beginArray();
+ while (mReader.hasNext()) {
+ Event.UinputControlCode controlCode = null;
+ IntStream data = null;
+ mReader.beginObject();
+ while (mReader.hasNext()) {
+ String name = mReader.nextName();
+ switch (name) {
+ case "type":
+ controlCode = readUinputControlCode();
+ break;
+ case "data":
+ Objects.requireNonNull(controlCode,
+ "Configuration 'type' must be specified before 'data'.");
+ data = readDataForControlCode(controlCode)
+ .stream().mapToInt(Integer::intValue);
+ break;
+ default:
+ consumeRemainingElements();
+ mReader.endObject();
+ throw new IllegalStateException(
+ "Invalid key in device configuration: " + name);
+ }
+ }
+ mReader.endObject();
+ if (controlCode != null && data != null) {
+ final int[] existing = configuration.get(controlCode.getValue());
+ configuration.put(controlCode.getValue(), existing == null ? data.toArray()
+ : IntStream.concat(IntStream.of(existing), data).toArray());
+ }
+ }
+ mReader.endArray();
+ } catch (IllegalStateException | NumberFormatException e) {
+ consumeRemainingElements();
+ mReader.endArray();
+ throw new IllegalStateException("Encountered malformed data.", e);
+ }
+ return configuration;
+ }
+
+ private Event.UinputControlCode readUinputControlCode() throws IOException {
+ var code = readValueAsInt((controlTypeStr) -> {
+ for (Event.UinputControlCode controlCode : Event.UinputControlCode.values()) {
+ if (controlCode.getName().equals(controlTypeStr)) {
+ return controlCode.getValue();
+ }
+ }
+ return -1;
+ });
+ for (Event.UinputControlCode controlCode : Event.UinputControlCode.values()) {
+ if (controlCode.getValue() == code) {
+ return controlCode;
+ }
+ }
+ return null;
+ }
+
+ private List<Integer> readDataForControlCode(
+ Event.UinputControlCode controlCode) throws IOException {
+ return switch (controlCode) {
+ case UI_SET_EVBIT -> readArrayAsInts(this::readEvdevEventType);
+ case UI_SET_KEYBIT -> readArrayAsInts(() -> readEvdevEventCode(Event.EV_KEY));
+ case UI_SET_RELBIT -> readArrayAsInts(() -> readEvdevEventCode(Event.EV_REL));
+ case UI_SET_ABSBIT -> readArrayAsInts(() -> readEvdevEventCode(Event.EV_ABS));
+ case UI_SET_MSCBIT -> readArrayAsInts(() -> readEvdevEventCode(Event.EV_MSC));
+ case UI_SET_LEDBIT -> readArrayAsInts(() -> readEvdevEventCode(Event.EV_LED));
+ case UI_SET_SNDBIT -> readArrayAsInts(() -> readEvdevEventCode(Event.EV_SND));
+ case UI_SET_FFBIT -> readArrayAsInts(() -> readEvdevEventCode(Event.EV_FF));
+ case UI_SET_SWBIT -> readArrayAsInts(() -> readEvdevEventCode(Event.EV_SW));
+ case UI_SET_PROPBIT -> readArrayAsInts(this::readEvdevInputProp);
+ };
+ }
+
+ interface IntValueReader {
+ int readNextValue() throws IOException;
+ }
+
+ private ArrayList<Integer> readArrayAsInts(
+ IntValueReader nextValueReader) throws IOException {
+ ArrayList<Integer> data = new ArrayList<>();
+ try {
+ mReader.beginArray();
+ while (mReader.hasNext()) {
+ data.add(nextValueReader.readNextValue());
+ }
+ mReader.endArray();
+ } catch (IllegalStateException | NumberFormatException e) {
+ consumeRemainingElements();
+ mReader.endArray();
+ throw new IllegalStateException("Encountered malformed data.", e);
+ }
+ return data;
+ }
+
+ private InputAbsInfo readAbsInfo() throws IllegalStateException, IOException {
+ InputAbsInfo absInfo = new InputAbsInfo();
+ try {
+ mReader.beginObject();
+ while (mReader.hasNext()) {
+ String name = mReader.nextName();
+ switch (name) {
+ case "value" -> absInfo.value = readInt();
+ case "minimum" -> absInfo.minimum = readInt();
+ case "maximum" -> absInfo.maximum = readInt();
+ case "fuzz" -> absInfo.fuzz = readInt();
+ case "flat" -> absInfo.flat = readInt();
+ case "resolution" -> absInfo.resolution = readInt();
+ default -> {
+ consumeRemainingElements();
+ mReader.endObject();
+ throw new IllegalStateException("Invalid key in abs info: " + name);
+ }
+ }
+ }
+ mReader.endObject();
+ } catch (IllegalStateException | NumberFormatException e) {
+ consumeRemainingElements();
+ mReader.endObject();
+ throw new IllegalStateException("Encountered malformed data.", e);
+ }
+ return absInfo;
+ }
+
+ private SparseArray<InputAbsInfo> readAbsInfoArray()
+ throws IllegalStateException, IOException {
+ SparseArray<InputAbsInfo> infoArray = new SparseArray<>();
+ try {
+ mReader.beginArray();
+ while (mReader.hasNext()) {
+ int type = 0;
+ InputAbsInfo absInfo = null;
+ mReader.beginObject();
+ while (mReader.hasNext()) {
+ String name = mReader.nextName();
+ switch (name) {
+ case "code" -> type = readEvdevEventCode(Event.EV_ABS);
+ case "info" -> absInfo = readAbsInfo();
+ default -> {
+ consumeRemainingElements();
+ mReader.endObject();
+ throw new IllegalStateException("Invalid key in abs info array: "
+ + name);
+ }
+ }
+ }
+ mReader.endObject();
+ if (absInfo != null) {
+ infoArray.put(type, absInfo);
+ }
+ }
+ mReader.endArray();
+ } catch (IllegalStateException | NumberFormatException e) {
+ consumeRemainingElements();
+ mReader.endArray();
+ throw new IllegalStateException("Encountered malformed data.", e);
+ }
+ return infoArray;
+ }
+
+ private int readEvdevEventType() throws IOException {
+ return readValueAsInt(Device::getEvdevEventTypeByLabel);
+ }
+
+ private int readEvdevEventCode(int type) throws IOException {
+ return readValueAsInt((str) -> Device.getEvdevEventCodeByLabel(type, str));
+ }
+
+ private int readEvdevInputProp() throws IOException {
+ return readValueAsInt(Device::getEvdevInputPropByLabel);
+ }
+
+ private void consumeRemainingElements() throws IOException {
+ while (mReader.hasNext()) {
+ mReader.skipValue();
+ }
+ }
+
+ private static void error(String msg, Exception e) {
+ System.out.println(msg);
+ Log.e(TAG, msg);
+ if (e != null) {
+ Log.e(TAG, Log.getStackTraceString(e));
+ }
+ }
+}
diff --git a/cmds/uinput/src/com/android/commands/uinput/Uinput.java b/cmds/uinput/src/com/android/commands/uinput/Uinput.java
index 47b7a354..16342ef 100644
--- a/cmds/uinput/src/com/android/commands/uinput/Uinput.java
+++ b/cmds/uinput/src/com/android/commands/uinput/Uinput.java
@@ -35,7 +35,7 @@
public class Uinput {
private static final String TAG = "UINPUT";
- private final Event.Reader mReader;
+ private final JsonStyleParser mParser;
private final SparseArray<Device> mDevices;
private static void usage() {
@@ -74,7 +74,7 @@
private Uinput(InputStream in) {
mDevices = new SparseArray<Device>();
try {
- mReader = new Event.Reader(new InputStreamReader(in, "UTF-8"));
+ mParser = new JsonStyleParser(new InputStreamReader(in, "UTF-8"));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
@@ -83,7 +83,7 @@
private void run() {
try {
Event e = null;
- while ((e = mReader.getNextEvent()) != null) {
+ while ((e = mParser.getNextEvent()) != null) {
process(e);
}
} catch (IOException ex) {