From 5b70661c458759e123a08a097cc8b3b58af74795 Mon Sep 17 00:00:00 2001 From: Solti Ho <solti@google.com> Date: Sun, 11 Feb 2024 19:49:01 +0000 Subject: [PATCH] Revert "uinput: use nanoseconds for delay durations" Revert submission 26154399 Reason for revert: b/324707605 Reverted changes: /q/submissionid:26154399 Change-Id: Ie1e20baefa998f0b69fd56ffa780ea3d3cd038db --- .../com/android/commands/uinput/Device.java | 36 +++++-------------- .../android/commands/uinput/EvemuParser.java | 6 ++-- .../com/android/commands/uinput/Event.java | 14 ++++---- .../commands/uinput/JsonStyleParser.java | 3 +- .../com/android/commands/uinput/Uinput.java | 2 +- .../uinput/tests/EvemuParserTest.java | 10 +++--- 6 files changed, 26 insertions(+), 45 deletions(-) diff --git a/cmds/uinput/src/com/android/commands/uinput/Device.java b/cmds/uinput/src/com/android/commands/uinput/Device.java index 3cbc4986e330..787055c8cd89 100644 --- a/cmds/uinput/src/com/android/commands/uinput/Device.java +++ b/cmds/uinput/src/com/android/commands/uinput/Device.java @@ -55,7 +55,7 @@ public class Device { private final SparseArray<InputAbsInfo> mAbsInfo; private final OutputStream mOutputStream; private final Object mCond = new Object(); - private long mTimeToSendNanos; + private long mTimeToSend; static { System.loadLibrary("uinputcommand_jni"); @@ -101,13 +101,7 @@ public class Device { } mHandler.obtainMessage(MSG_OPEN_UINPUT_DEVICE, args).sendToTarget(); - mTimeToSendNanos = SystemClock.uptimeNanos(); - } - - private long getTimeToSendMillis() { - // This should be the same as (long) Math.ceil(mTimeToSendNanos / 1_000_000.0), except - // without the precision loss that comes from converting from long to double and back. - return mTimeToSendNanos / 1_000_000 + ((mTimeToSendNanos % 1_000_000 > 0) ? 1 : 0); + mTimeToSend = SystemClock.uptimeMillis(); } /** @@ -118,26 +112,16 @@ public class Device { public void injectEvent(int[] events) { // if two messages are sent at identical time, they will be processed in order received Message msg = mHandler.obtainMessage(MSG_INJECT_EVENT, events); - mHandler.sendMessageAtTime(msg, getTimeToSendMillis()); + mHandler.sendMessageAtTime(msg, mTimeToSend); } /** - * Delay subsequent device activity by the specified amount of time. - * - * <p>Note that although the delay is specified in nanoseconds, due to limitations of {@link - * Handler}'s API, scheduling only occurs with millisecond precision. When scheduling an - * injection or sync, the time at which it is scheduled will be rounded up to the nearest - * millisecond. While this means that a particular injection cannot be scheduled precisely, - * rounding errors will not accumulate over time. For example, if five injections are scheduled - * with a delay of 1,200,000ns before each one, the total delay will be 6ms, as opposed to the - * 10ms it would have been if each individual delay had been rounded up (as {@link EvemuParser} - * would otherwise have to do to avoid sending timestamps that are in the future). + * Impose a delay to the device for execution. * - * @param delayNanos Time to delay in unit of nanoseconds. + * @param delay Time to delay in unit of milliseconds. */ - public void addDelayNanos(long delayNanos) { - mTimeToSendNanos = - Math.max(SystemClock.uptimeNanos(), mTimeToSendNanos) + delayNanos; + public void addDelay(int delay) { + mTimeToSend = Math.max(SystemClock.uptimeMillis(), mTimeToSend) + delay; } /** @@ -147,8 +131,7 @@ public class Device { * @param syncToken The token for this sync command. */ public void syncEvent(String syncToken) { - mHandler.sendMessageAtTime( - mHandler.obtainMessage(MSG_SYNC_EVENT, syncToken), getTimeToSendMillis()); + mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_SYNC_EVENT, syncToken), mTimeToSend); } /** @@ -157,8 +140,7 @@ public class Device { */ public void close() { Message msg = mHandler.obtainMessage(MSG_CLOSE_UINPUT_DEVICE); - mHandler.sendMessageAtTime( - msg, Math.max(SystemClock.uptimeMillis(), getTimeToSendMillis()) + 1); + mHandler.sendMessageAtTime(msg, Math.max(SystemClock.uptimeMillis(), mTimeToSend) + 1); try { synchronized (mCond) { mCond.wait(); diff --git a/cmds/uinput/src/com/android/commands/uinput/EvemuParser.java b/cmds/uinput/src/com/android/commands/uinput/EvemuParser.java index cf9744d2172f..7652f2403f6e 100644 --- a/cmds/uinput/src/com/android/commands/uinput/EvemuParser.java +++ b/cmds/uinput/src/com/android/commands/uinput/EvemuParser.java @@ -44,7 +44,7 @@ public class EvemuParser implements EventParser { * recordings, this will always be the same. */ private static final int DEVICE_ID = 1; - private static final int REGISTRATION_DELAY_NANOS = 500_000_000; + private static final int REGISTRATION_DELAY_MILLIS = 500; private static class CommentAwareReader { private final LineNumberReader mReader; @@ -152,7 +152,7 @@ public class EvemuParser implements EventParser { final Event.Builder delayEb = new Event.Builder(); delayEb.setId(DEVICE_ID); delayEb.setCommand(Event.Command.DELAY); - delayEb.setDurationNanos(REGISTRATION_DELAY_NANOS); + delayEb.setDurationMillis(REGISTRATION_DELAY_MILLIS); mQueuedEvents.add(delayEb.build()); } @@ -204,7 +204,7 @@ public class EvemuParser implements EventParser { final Event.Builder delayEb = new Event.Builder(); delayEb.setId(DEVICE_ID); delayEb.setCommand(Event.Command.DELAY); - delayEb.setDurationNanos(delayMicros * 1000); + delayEb.setDurationMillis((int) (delayMicros / 1000)); return delayEb.build(); } } diff --git a/cmds/uinput/src/com/android/commands/uinput/Event.java b/cmds/uinput/src/com/android/commands/uinput/Event.java index c4b4f21f501f..0f16a27aac1d 100644 --- a/cmds/uinput/src/com/android/commands/uinput/Event.java +++ b/cmds/uinput/src/com/android/commands/uinput/Event.java @@ -100,7 +100,7 @@ public class Event { private int mBusId; private int[] mInjections; private SparseArray<int[]> mConfiguration; - private long mDurationNanos; + private int mDurationMillis; private int mFfEffectsMax = 0; private String mInputPort; private SparseArray<InputAbsInfo> mAbsInfo; @@ -150,8 +150,8 @@ public class Event { return mConfiguration; } - public long getDurationNanos() { - return mDurationNanos; + public int getDurationMillis() { + return mDurationMillis; } public int getFfEffectsMax() { @@ -182,7 +182,7 @@ public class Event { + ", busId=" + mBusId + ", events=" + Arrays.toString(mInjections) + ", configuration=" + mConfiguration - + ", duration=" + mDurationNanos + "ns" + + ", duration=" + mDurationMillis + "ms" + ", ff_effects_max=" + mFfEffectsMax + ", port=" + mInputPort + "}"; @@ -237,8 +237,8 @@ public class Event { mEvent.mBusId = busId; } - public void setDurationNanos(long durationNanos) { - mEvent.mDurationNanos = durationNanos; + public void setDurationMillis(int durationMillis) { + mEvent.mDurationMillis = durationMillis; } public void setFfEffectsMax(int ffEffectsMax) { @@ -271,7 +271,7 @@ public class Event { } } case DELAY -> { - if (mEvent.mDurationNanos <= 0) { + if (mEvent.mDurationMillis <= 0) { throw new IllegalStateException("Delay has missing or invalid duration"); } } diff --git a/cmds/uinput/src/com/android/commands/uinput/JsonStyleParser.java b/cmds/uinput/src/com/android/commands/uinput/JsonStyleParser.java index 6994f0cb0e4b..ed3ff33f7e52 100644 --- a/cmds/uinput/src/com/android/commands/uinput/JsonStyleParser.java +++ b/cmds/uinput/src/com/android/commands/uinput/JsonStyleParser.java @@ -71,8 +71,7 @@ public class JsonStyleParser implements EventParser { case "configuration" -> eb.setConfiguration(readConfiguration()); case "ff_effects_max" -> eb.setFfEffectsMax(readInt()); case "abs_info" -> eb.setAbsInfo(readAbsInfoArray()); - // Duration is specified in milliseconds in the JSON-style format. - case "duration" -> eb.setDurationNanos(readInt() * 1_000_000L); + case "duration" -> eb.setDurationMillis(readInt()); case "port" -> eb.setInputPort(mReader.nextString()); case "syncToken" -> eb.setSyncToken(mReader.nextString()); default -> mReader.skipValue(); diff --git a/cmds/uinput/src/com/android/commands/uinput/Uinput.java b/cmds/uinput/src/com/android/commands/uinput/Uinput.java index 0ef26382850e..04df27987d58 100644 --- a/cmds/uinput/src/com/android/commands/uinput/Uinput.java +++ b/cmds/uinput/src/com/android/commands/uinput/Uinput.java @@ -135,7 +135,7 @@ public class Uinput { case REGISTER -> error("Device id=" + e.getId() + " is already registered. Ignoring event."); case INJECT -> d.injectEvent(e.getInjections()); - case DELAY -> d.addDelayNanos(e.getDurationNanos()); + case DELAY -> d.addDelay(e.getDurationMillis()); case SYNC -> d.syncEvent(e.getSyncToken()); } } diff --git a/cmds/uinput/tests/src/com/android/commands/uinput/tests/EvemuParserTest.java b/cmds/uinput/tests/src/com/android/commands/uinput/tests/EvemuParserTest.java index 140045226cbb..06b0aac271ad 100644 --- a/cmds/uinput/tests/src/com/android/commands/uinput/tests/EvemuParserTest.java +++ b/cmds/uinput/tests/src/com/android/commands/uinput/tests/EvemuParserTest.java @@ -189,10 +189,10 @@ public class EvemuParserTest { .containsExactly(eventType, eventCode, value).inOrder(); } - private void assertDelayEvent(Event event, int durationMicros) { + private void assertDelayEvent(Event event, int durationMillis) { assertThat(event).isNotNull(); assertThat(event.getCommand()).isEqualTo(Event.Command.DELAY); - assertThat(event.getDurationMicros()).isEqualTo(durationMicros); + assertThat(event.getDurationMillis()).isEqualTo(durationMillis); } @Test @@ -231,12 +231,12 @@ public class EvemuParserTest { assertInjectEvent(parser.getNextEvent(), 0x1, 0x15, 1); assertInjectEvent(parser.getNextEvent(), 0x0, 0x0, 0); - assertDelayEvent(parser.getNextEvent(), 10000); + assertDelayEvent(parser.getNextEvent(), 10); assertInjectEvent(parser.getNextEvent(), 0x1, 0x15, 0); assertInjectEvent(parser.getNextEvent(), 0x0, 0x0, 0); - assertDelayEvent(parser.getNextEvent(), 1000000); + assertDelayEvent(parser.getNextEvent(), 1000); assertInjectEvent(parser.getNextEvent(), 0x1, 0x15, 1); assertInjectEvent(parser.getNextEvent(), 0x0, 0x0, 0); @@ -490,7 +490,7 @@ public class EvemuParserTest { assertInjectEvent(parser.getNextEvent(), 0x3, 0x18, 56); assertInjectEvent(parser.getNextEvent(), 0x0, 0x0, 0); - assertDelayEvent(parser.getNextEvent(), 6080); + assertDelayEvent(parser.getNextEvent(), 6); assertInjectEvent(parser.getNextEvent(), 0x3, 0x0035, 888); } -- GitLab