From 687a05d319eb163c39535813f23f4f26f4b473b2 Mon Sep 17 00:00:00 2001 From: Adrian Roos Date: Wed, 18 Jan 2023 22:12:13 +0100 Subject: [PATCH] IntResultReceiver: fix clearing on dispatch Fixes an issue where mConsumer was cleared too early for any executor other than Runnable::run, leading to an NPE when the Runnable is invoked on the Executor. Fixes: 265457058 Test: atest InputConnectionEndToEndTest Change-Id: Ifc8e435e02520eb29c9631427daa5a1a1ea0ccf0 --- .../IRemoteInputConnectionInvoker.java | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/core/java/android/inputmethodservice/IRemoteInputConnectionInvoker.java b/core/java/android/inputmethodservice/IRemoteInputConnectionInvoker.java index 8759a6a263485..a75994c3c7ae9 100644 --- a/core/java/android/inputmethodservice/IRemoteInputConnectionInvoker.java +++ b/core/java/android/inputmethodservice/IRemoteInputConnectionInvoker.java @@ -72,29 +72,32 @@ final class IRemoteInputConnectionInvoker { * callback. */ private static final class IntResultReceiver extends ResultReceiver { - @NonNull + @Nullable private IntConsumer mConsumer; - @NonNull + @Nullable private Executor mExecutor; IntResultReceiver(@NonNull Executor executor, @NonNull IntConsumer consumer) { super(null); + Objects.requireNonNull(executor); + Objects.requireNonNull(consumer); mExecutor = executor; mConsumer = consumer; } @Override protected void onReceiveResult(int resultCode, Bundle resultData) { - if (mExecutor != null && mConsumer != null) { - mExecutor.execute(() -> mConsumer.accept(resultCode)); - // provide callback only once. - clear(); + final Executor executor; + final IntConsumer consumer; + synchronized (this) { + executor = mExecutor; + consumer = mConsumer; + mExecutor = null; + mConsumer = null; + } + if (executor != null && consumer != null) { + executor.execute(() -> consumer.accept(resultCode)); } - } - - private void clear() { - mExecutor = null; - mConsumer = null; } };