Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
/ engine Public archive
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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 -----

Expand Down Expand Up @@ -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);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ class DartMessenger implements BinaryMessenger, PlatformMessageHandler {

@NonNull private final ConcurrentHashMap<String, HandlerInfo> messageHandlers;

@NonNull private final HashMap<String, DartMessengerTaskQueue> taskQueues;

@NonNull private final Map<Integer, BinaryMessenger.BinaryReply> pendingReplies;
private int nextReplyId = 1;

Expand All @@ -51,7 +49,6 @@ class DartMessenger implements BinaryMessenger, PlatformMessageHandler {
this.pendingReplies = new HashMap<>();
this.createdTaskQueues = new WeakHashMap<TaskQueue, DartMessengerTaskQueue>();
this.taskQueueFactory = taskQueueFactory;
this.taskQueues = new HashMap<>();
}

DartMessenger(@NonNull FlutterJNI flutterJNI) {
Expand Down Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,13 @@ public void send(@Nullable T message, @Nullable final Reply<T> callback) {
*/
@UiThread
public void setMessageHandler(@Nullable final MessageHandler<T> 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));
}
Comment on lines +128 to +134
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: add a comment here (perhaps a TODO) explaining why we're doing this and that it can be simplified after the next stable roll.

}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please link a github issue.

throw new UnsupportedOperationException("makeBackgroundTaskQueue not implemented.");
}

/**
* Sends a binary message to the Flutter application.
Expand Down Expand Up @@ -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.
*
* <p>A null value for taskQueue means to execute the handler on the platform thread.
* <p>Registration overwrites any previous registration for the same channel name. Use a null
* handler to deregister.
*
* <p>See also: {@link BinaryMessenger#makeBackgroundTaskQueue()}
* <p>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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}

/**
Expand Down
4 changes: 2 additions & 2 deletions shell/platform/android/io/flutter/view/FlutterNativeView.java
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
4 changes: 2 additions & 2 deletions shell/platform/android/io/flutter/view/FlutterView.java
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 {
Expand All @@ -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
Expand All @@ -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);
Expand All @@ -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');
Expand All @@ -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
Expand All @@ -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');
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down