diff --git a/shell/platform/android/io/flutter/embedding/engine/dart/DartExecutor.java b/shell/platform/android/io/flutter/embedding/engine/dart/DartExecutor.java index 80f853c577b95..5580d7a5cd258 100644 --- a/shell/platform/android/io/flutter/embedding/engine/dart/DartExecutor.java +++ b/shell/platform/android/io/flutter/embedding/engine/dart/DartExecutor.java @@ -208,8 +208,11 @@ public void setMessageHandler( @Deprecated @Override @UiThread - public void setTaskQueue(@NonNull String channel, @Nullable TaskQueue taskQueue) { - binaryMessenger.setTaskQueue(channel, taskQueue); + public void setMessageHandler( + @NonNull String channel, + @Nullable BinaryMessenger.BinaryMessageHandler handler, + @Nullable TaskQueue taskQueue) { + binaryMessenger.setMessageHandler(channel, handler, taskQueue); } // ------ END BinaryMessenger ----- @@ -439,8 +442,11 @@ public void setMessageHandler( @Override @UiThread - public void setTaskQueue(@NonNull String channel, @Nullable TaskQueue taskQueue) { - messenger.setTaskQueue(channel, taskQueue); + public void setMessageHandler( + @NonNull String channel, + @Nullable BinaryMessenger.BinaryMessageHandler handler, + @Nullable TaskQueue taskQueue) { + messenger.setMessageHandler(channel, handler, taskQueue); } } } diff --git a/shell/platform/android/io/flutter/embedding/engine/dart/DartMessenger.java b/shell/platform/android/io/flutter/embedding/engine/dart/DartMessenger.java index 5744ca37d04b5..c5faf03b5dd40 100644 --- a/shell/platform/android/io/flutter/embedding/engine/dart/DartMessenger.java +++ b/shell/platform/android/io/flutter/embedding/engine/dart/DartMessenger.java @@ -34,8 +34,6 @@ class DartMessenger implements BinaryMessenger, PlatformMessageHandler { @NonNull private final ConcurrentHashMap messageHandlers; - @NonNull private final HashMap taskQueues; - @NonNull private final Map pendingReplies; private int nextReplyId = 1; @@ -51,7 +49,6 @@ class DartMessenger implements BinaryMessenger, PlatformMessageHandler { this.pendingReplies = new HashMap<>(); this.createdTaskQueues = new WeakHashMap(); this.taskQueueFactory = taskQueueFactory; - this.taskQueues = new HashMap<>(); } DartMessenger(@NonNull FlutterJNI flutterJNI) { @@ -116,36 +113,31 @@ public TaskQueue makeBackgroundTaskQueue() { @Override public void setMessageHandler( @NonNull String channel, @Nullable BinaryMessenger.BinaryMessageHandler handler) { + setMessageHandler(channel, handler, null); + } + + @Override + public void setMessageHandler( + @NonNull String channel, + @Nullable BinaryMessenger.BinaryMessageHandler handler, + @Nullable TaskQueue taskQueue) { if (handler == null) { Log.v(TAG, "Removing handler for channel '" + channel + "'"); messageHandlers.remove(channel); } else { - DartMessengerTaskQueue dartMessengerTaskQueue = taskQueues.get(channel); + DartMessengerTaskQueue dartMessengerTaskQueue = null; + if (taskQueue != null) { + dartMessengerTaskQueue = createdTaskQueues.get(taskQueue); + if (dartMessengerTaskQueue == null) { + throw new IllegalArgumentException( + "Unrecognized TaskQueue, use BinaryMessenger to create your TaskQueue (ex makeBackgroundTaskQueue)."); + } + } Log.v(TAG, "Setting handler for channel '" + channel + "'"); messageHandlers.put(channel, new HandlerInfo(handler, dartMessengerTaskQueue)); } } - @Override - public void setTaskQueue(@NonNull String channel, @Nullable BinaryMessenger.TaskQueue taskQueue) { - DartMessengerTaskQueue dartMessengerTaskQueue = null; - if (taskQueue == null) { - taskQueues.remove(channel); - } else { - dartMessengerTaskQueue = createdTaskQueues.get(taskQueue); - if (dartMessengerTaskQueue == null) { - throw new IllegalArgumentException( - "Unrecognized TaskQueue, use BinaryMessenger to create your TaskQueue (ex makeBackgroundTaskQueue)."); - } - taskQueues.put(channel, dartMessengerTaskQueue); - } - HandlerInfo existingHandlerInfo = messageHandlers.get(channel); - if (existingHandlerInfo != null) { - messageHandlers.put( - channel, new HandlerInfo(existingHandlerInfo.handler, dartMessengerTaskQueue)); - } - } - @Override @UiThread public void send(@NonNull String channel, @NonNull ByteBuffer message) { diff --git a/shell/platform/android/io/flutter/plugin/common/BasicMessageChannel.java b/shell/platform/android/io/flutter/plugin/common/BasicMessageChannel.java index de790f117a1cb..0427307d087ff 100644 --- a/shell/platform/android/io/flutter/plugin/common/BasicMessageChannel.java +++ b/shell/platform/android/io/flutter/plugin/common/BasicMessageChannel.java @@ -122,8 +122,13 @@ public void send(@Nullable T message, @Nullable final Reply callback) { */ @UiThread public void setMessageHandler(@Nullable final MessageHandler handler) { - messenger.setMessageHandler(name, handler == null ? null : new IncomingMessageHandler(handler)); - messenger.setTaskQueue(name, handler == null ? null : taskQueue); + if (taskQueue != null) { + messenger.setMessageHandler( + name, handler == null ? null : new IncomingMessageHandler(handler), taskQueue); + } else { + messenger.setMessageHandler( + name, handler == null ? null : new IncomingMessageHandler(handler)); + } } /** diff --git a/shell/platform/android/io/flutter/plugin/common/BinaryMessenger.java b/shell/platform/android/io/flutter/plugin/common/BinaryMessenger.java index 6cf4f6c6b17e8..b2b32fe975bd9 100644 --- a/shell/platform/android/io/flutter/plugin/common/BinaryMessenger.java +++ b/shell/platform/android/io/flutter/plugin/common/BinaryMessenger.java @@ -42,7 +42,10 @@ public interface TaskQueue {} * serial. */ @UiThread - TaskQueue makeBackgroundTaskQueue(); + default TaskQueue makeBackgroundTaskQueue() { + // TODO(aaclarke): Remove default implementation when it is safe for Google Flutter users. + throw new UnsupportedOperationException("makeBackgroundTaskQueue not implemented."); + } /** * Sends a binary message to the Flutter application. @@ -85,19 +88,32 @@ public interface TaskQueue {} void setMessageHandler(@NonNull String channel, @Nullable BinaryMessageHandler handler); /** - * Registers a TaskQueue for a specified channel which controls the threading model to follow when - * invoking the message handler. + * Registers a handler to be invoked when the Flutter application sends a message to its host + * platform. * - *

A null value for taskQueue means to execute the handler on the platform thread. + *

Registration overwrites any previous registration for the same channel name. Use a null + * handler to deregister. * - *

See also: {@link BinaryMessenger#makeBackgroundTaskQueue()} + *

If no handler has been registered for a particular channel, any incoming message on that + * channel will be handled silently by sending a null reply. * * @param channel the name {@link String} of the channel. + * @param handler a {@link BinaryMessageHandler} to be invoked on incoming messages, or null. * @param taskQueue a {@link BinaryMessenger.TaskQueue} that specifies what thread will execute * the handler. Specifying null means execute on the platform thread. */ @UiThread - void setTaskQueue(@NonNull String channel, @Nullable TaskQueue taskQueue); + default void setMessageHandler( + @NonNull String channel, + @Nullable BinaryMessageHandler handler, + @Nullable TaskQueue taskQueue) { + // TODO(aaclarke): Remove default implementation when it is safe for Google Flutter users. + if (taskQueue != null) { + throw new UnsupportedOperationException( + "setMessageHandler called with nonnull taskQueue is not supported."); + } + setMessageHandler(channel, handler); + } /** Handler for incoming binary messages from Flutter. */ interface BinaryMessageHandler { diff --git a/shell/platform/android/io/flutter/plugin/common/EventChannel.java b/shell/platform/android/io/flutter/plugin/common/EventChannel.java index 3c21f7ef4b9ff..2138d037f5697 100644 --- a/shell/platform/android/io/flutter/plugin/common/EventChannel.java +++ b/shell/platform/android/io/flutter/plugin/common/EventChannel.java @@ -105,9 +105,13 @@ public EventChannel( */ @UiThread public void setStreamHandler(final StreamHandler handler) { - messenger.setMessageHandler( - name, handler == null ? null : new IncomingStreamRequestHandler(handler)); - messenger.setTaskQueue(name, handler == null ? null : taskQueue); + if (taskQueue != null) { + messenger.setMessageHandler( + name, handler == null ? null : new IncomingStreamRequestHandler(handler), taskQueue); + } else { + messenger.setMessageHandler( + name, handler == null ? null : new IncomingStreamRequestHandler(handler)); + } } /** diff --git a/shell/platform/android/io/flutter/plugin/common/MethodChannel.java b/shell/platform/android/io/flutter/plugin/common/MethodChannel.java index 32ef488eb3879..615a4fbd069e3 100644 --- a/shell/platform/android/io/flutter/plugin/common/MethodChannel.java +++ b/shell/platform/android/io/flutter/plugin/common/MethodChannel.java @@ -137,9 +137,13 @@ public void invokeMethod(String method, @Nullable Object arguments, @Nullable Re */ @UiThread public void setMethodCallHandler(final @Nullable MethodCallHandler handler) { - messenger.setMessageHandler( - name, handler == null ? null : new IncomingMethodCallHandler(handler)); - messenger.setTaskQueue(name, handler == null ? null : taskQueue); + if (taskQueue != null) { + messenger.setMessageHandler( + name, handler == null ? null : new IncomingMethodCallHandler(handler), taskQueue); + } else { + messenger.setMessageHandler( + name, handler == null ? null : new IncomingMethodCallHandler(handler)); + } } /** diff --git a/shell/platform/android/io/flutter/view/FlutterNativeView.java b/shell/platform/android/io/flutter/view/FlutterNativeView.java index cc5286749d849..c44a23c9982bf 100644 --- a/shell/platform/android/io/flutter/view/FlutterNativeView.java +++ b/shell/platform/android/io/flutter/view/FlutterNativeView.java @@ -155,8 +155,8 @@ public void setMessageHandler(String channel, BinaryMessageHandler handler) { @Override @UiThread - public void setTaskQueue(String channel, TaskQueue taskQueue) { - dartExecutor.getBinaryMessenger().setTaskQueue(channel, taskQueue); + public void setMessageHandler(String channel, BinaryMessageHandler handler, TaskQueue taskQueue) { + dartExecutor.getBinaryMessenger().setMessageHandler(channel, handler, taskQueue); } /*package*/ FlutterJNI getFlutterJNI() { diff --git a/shell/platform/android/io/flutter/view/FlutterView.java b/shell/platform/android/io/flutter/view/FlutterView.java index 9cdd53d0969d1..317ec6562a1ca 100644 --- a/shell/platform/android/io/flutter/view/FlutterView.java +++ b/shell/platform/android/io/flutter/view/FlutterView.java @@ -852,8 +852,8 @@ public void setMessageHandler(String channel, BinaryMessageHandler handler) { @Override @UiThread - public void setTaskQueue(String channel, TaskQueue taskQueue) { - mNativeView.setTaskQueue(channel, taskQueue); + public void setMessageHandler(String channel, BinaryMessageHandler handler, TaskQueue taskQueue) { + mNativeView.setMessageHandler(channel, handler, taskQueue); } /** Listener will be called on the Android UI thread once when Flutter renders the first frame. */ diff --git a/shell/platform/android/test/io/flutter/embedding/engine/dart/DartMessengerTest.java b/shell/platform/android/test/io/flutter/embedding/engine/dart/DartMessengerTest.java index 67653970f4b14..4e7a6fdb7c2e1 100644 --- a/shell/platform/android/test/io/flutter/embedding/engine/dart/DartMessengerTest.java +++ b/shell/platform/android/test/io/flutter/embedding/engine/dart/DartMessengerTest.java @@ -14,7 +14,6 @@ import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.BinaryMessenger.BinaryMessageHandler; import java.nio.ByteBuffer; -import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; @@ -24,7 +23,7 @@ @Config(manifest = Config.NONE) @RunWith(RobolectricTestRunner.class) public class DartMessengerTest { - SynchronousTaskQueue synchronousTaskQueue = null; + SynchronousTaskQueue synchronousTaskQueue = new SynchronousTaskQueue(); private static class ReportingUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler { @@ -37,21 +36,9 @@ public void uncaughtException(Thread t, Throwable e) { } private static class SynchronousTaskQueue implements DartMessengerTaskQueue { - private boolean didRun = false; - public void dispatch(Runnable runnable) { - didRun = true; runnable.run(); } - - public boolean getDidRun() { - return didRun; - } - } - - @Before - public void setUp() { - synchronousTaskQueue = new SynchronousTaskQueue(); } @Test @@ -72,8 +59,7 @@ public void itHandlesErrors() { .when(throwingHandler) .onMessage(any(ByteBuffer.class), any(DartMessenger.Reply.class)); BinaryMessenger.TaskQueue taskQueue = messenger.makeBackgroundTaskQueue(); - messenger.setMessageHandler("test", throwingHandler); - messenger.setTaskQueue("test", taskQueue); + messenger.setMessageHandler("test", throwingHandler, taskQueue); messenger.handleMessageFromDart("test", ByteBuffer.allocate(0), 0, 0); assertNotNull(reportingHandler.latestException); assertTrue(reportingHandler.latestException instanceof AssertionError); @@ -92,8 +78,7 @@ public void givesDirectByteBuffer() { wasDirect[0] = message.isDirect(); }; BinaryMessenger.TaskQueue taskQueue = messenger.makeBackgroundTaskQueue(); - messenger.setMessageHandler(channel, handler); - messenger.setTaskQueue(channel, taskQueue); + messenger.setMessageHandler(channel, handler, taskQueue); final ByteBuffer message = ByteBuffer.allocateDirect(4 * 2); message.rewind(); message.putChar('a'); @@ -102,31 +87,6 @@ public void givesDirectByteBuffer() { message.putChar('d'); messenger.handleMessageFromDart(channel, message, /*replyId=*/ 123, 0); assertTrue(wasDirect[0]); - assertTrue(synchronousTaskQueue.didRun); - } - - @Test - public void setTaskQueueFirst() { - // The same test as givesDirectByteBuffer, but calls setTaskQueue before setMessageHandler. - final FlutterJNI fakeFlutterJni = mock(FlutterJNI.class); - final DartMessenger messenger = new DartMessenger(fakeFlutterJni, () -> synchronousTaskQueue); - final String channel = "foobar"; - final boolean[] wasDirect = {false}; - final BinaryMessenger.BinaryMessageHandler handler = - (message, reply) -> { - wasDirect[0] = message.isDirect(); - }; - BinaryMessenger.TaskQueue taskQueue = messenger.makeBackgroundTaskQueue(); - messenger.setTaskQueue(channel, taskQueue); - messenger.setMessageHandler(channel, handler); - final ByteBuffer message = ByteBuffer.allocateDirect(4 * 2); - message.rewind(); - message.putChar('a'); - message.putChar('b'); - message.putChar('c'); - message.putChar('d'); - messenger.handleMessageFromDart(channel, message, /*replyId=*/ 123, 0); - assertTrue(synchronousTaskQueue.didRun); } @Test @@ -143,8 +103,7 @@ public void directByteBufferLimitZeroAfterUsage() { assertEquals(bufferSize, byteBuffers[0].limit()); }; BinaryMessenger.TaskQueue taskQueue = messenger.makeBackgroundTaskQueue(); - messenger.setMessageHandler(channel, handler); - messenger.setTaskQueue(channel, taskQueue); + messenger.setMessageHandler(channel, handler, taskQueue); final ByteBuffer message = ByteBuffer.allocateDirect(bufferSize); message.rewind(); message.putChar('a'); @@ -202,8 +161,7 @@ public void cleansUpMessageData() throws InterruptedException { (ByteBuffer message, BinaryMessenger.BinaryReply reply) -> { reply.reply(null); }; - messenger.setMessageHandler(channel, handler); - messenger.setTaskQueue(channel, taskQueue); + messenger.setMessageHandler(channel, handler, taskQueue); final ByteBuffer message = ByteBuffer.allocateDirect(4 * 2); int replyId = 1; long messageData = 1234; @@ -221,8 +179,7 @@ public void cleansUpMessageDataOnError() throws InterruptedException { (ByteBuffer message, BinaryMessenger.BinaryReply reply) -> { throw new RuntimeException("hello"); }; - messenger.setMessageHandler(channel, handler); - messenger.setTaskQueue(channel, taskQueue); + messenger.setMessageHandler(channel, handler, taskQueue); final ByteBuffer message = ByteBuffer.allocateDirect(4 * 2); int replyId = 1; long messageData = 1234;