| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| package io.flutter.plugin.common; |
| |
| import androidx.annotation.NonNull; |
| import androidx.annotation.Nullable; |
| import androidx.annotation.UiThread; |
| import java.nio.ByteBuffer; |
| |
| /** |
| * Facility for communicating with Flutter using asynchronous message passing with binary messages. |
| * The Flutter Dart code should use <a |
| * href="https://api.flutter.dev/flutter/services/BinaryMessages-class.html">BinaryMessages</a> to |
| * participate. |
| * |
| * <p>{@code BinaryMessenger} is expected to be utilized from a single thread throughout the |
| * duration of its existence. If created on the main thread, then all invocations should take place |
| * on the main thread. If created on a background thread, then all invocations should take place on |
| * that background thread. |
| * |
| * @see BasicMessageChannel , which supports message passing with Strings and semi-structured |
| * messages. |
| * @see MethodChannel , which supports communication using asynchronous method invocation. |
| * @see EventChannel , which supports communication using event streams. |
| */ |
| public interface BinaryMessenger { |
| /** |
| * An abstraction over the threading policy used to invoke message handlers. |
| * |
| * <p>These are generated by calling methods like {@link |
| * BinaryMessenger#makeBackgroundTaskQueue(TaskQueueOptions)} and can be passed into platform |
| * channels' constructors to control the threading policy for handling platform channels' |
| * messages. |
| */ |
| public interface TaskQueue {} |
| |
| /** Options that control how a TaskQueue should operate and be created. */ |
| public static class TaskQueueOptions { |
| private boolean isSerial = true; |
| |
| public boolean getIsSerial() { |
| return isSerial; |
| } |
| |
| /** |
| * Setter for `isSerial` property. |
| * |
| * <p>When this is true all tasks performed by the TaskQueue will be forced to happen serially |
| * (one completes before the other begins). |
| */ |
| public TaskQueueOptions setIsSerial(boolean isSerial) { |
| this.isSerial = isSerial; |
| return this; |
| } |
| } |
| |
| /** |
| * Creates a TaskQueue that executes the tasks serially on a background thread. |
| * |
| * <p>There is no guarantee that the tasks will execute on the same thread, just that execution is |
| * serial. This is could be problematic if your code relies on ThreadLocal storage or |
| * introspection about what thread is actually executing. |
| */ |
| @UiThread |
| default TaskQueue makeBackgroundTaskQueue() { |
| return makeBackgroundTaskQueue(new TaskQueueOptions()); |
| } |
| |
| /** |
| * Creates a TaskQueue that executes the tasks serially on a background thread. |
| * |
| * <p>{@link TaskQueueOptions} can be used to configure the task queue to execute tasks |
| * concurrently. Doing so can be more performant, though users need to ensure that the task |
| * handlers are thread-safe. |
| */ |
| @UiThread |
| default TaskQueue makeBackgroundTaskQueue(TaskQueueOptions options) { |
| // TODO(92582): 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. |
| * |
| * @param channel the name {@link String} of the logical channel used for the message. |
| * @param message the message payload, a direct-allocated {@link ByteBuffer} with the message |
| * bytes between position zero and current position, or null. |
| */ |
| @UiThread |
| void send(@NonNull String channel, @Nullable ByteBuffer message); |
| |
| /** |
| * Sends a binary message to the Flutter application, optionally expecting a reply. |
| * |
| * <p>Any uncaught exception thrown by the reply callback will be caught and logged. |
| * |
| * @param channel the name {@link String} of the logical channel used for the message. |
| * @param message the message payload, a direct-allocated {@link ByteBuffer} with the message |
| * bytes between position zero and current position, or null. |
| * @param callback a {@link BinaryReply} callback invoked when the Flutter application responds to |
| * the message, possibly null. |
| */ |
| @UiThread |
| void send(@NonNull String channel, @Nullable ByteBuffer message, @Nullable BinaryReply callback); |
| |
| /** |
| * Registers a handler to be invoked when the Flutter application sends a message to its host |
| * platform. |
| * |
| * <p>Registration overwrites any previous registration for the same channel name. Use a null |
| * handler to deregister. |
| * |
| * <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. |
| */ |
| @UiThread |
| void setMessageHandler(@NonNull String channel, @Nullable BinaryMessageHandler handler); |
| |
| /** |
| * Registers a handler to be invoked when the Flutter application sends a message to its host |
| * platform. |
| * |
| * <p>Registration overwrites any previous registration for the same channel name. Use a null |
| * handler to deregister. |
| * |
| * <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 |
| default void setMessageHandler( |
| @NonNull String channel, |
| @Nullable BinaryMessageHandler handler, |
| @Nullable TaskQueue taskQueue) { |
| // TODO(92582): 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); |
| } |
| |
| /** |
| * Enables the ability to queue messages received from Dart. |
| * |
| * <p>This is useful when there are pending channel handler registrations. For example, Dart may |
| * be initialized concurrently, and prior to the registration of the channel handlers. This |
| * implies that Dart may start sending messages while plugins are being registered. |
| */ |
| default void enableBufferingIncomingMessages() { |
| throw new UnsupportedOperationException("enableBufferingIncomingMessages not implemented."); |
| } |
| |
| /** |
| * Disables the ability to queue messages received from Dart. |
| * |
| * <p>This can be used after all pending channel handlers have been registered. |
| */ |
| default void disableBufferingIncomingMessages() { |
| throw new UnsupportedOperationException("disableBufferingIncomingMessages not implemented."); |
| } |
| |
| /** Handler for incoming binary messages from Flutter. */ |
| interface BinaryMessageHandler { |
| /** |
| * Handles the specified message. |
| * |
| * <p>Handler implementations must reply to all incoming messages, by submitting a single reply |
| * message to the given {@link BinaryReply}. Failure to do so will result in lingering Flutter |
| * reply handlers. The reply may be submitted asynchronously. |
| * |
| * <p>Any uncaught exception thrown by this method will be caught by the messenger |
| * implementation and logged, and a null reply message will be sent back to Flutter. |
| * |
| * @param message the message {@link ByteBuffer} payload, possibly null. |
| * @param reply A {@link BinaryReply} used for submitting a reply back to Flutter. |
| */ |
| @UiThread |
| void onMessage(@Nullable ByteBuffer message, @NonNull BinaryReply reply); |
| } |
| |
| /** |
| * Binary message reply callback. Used to submit a reply to an incoming message from Flutter. Also |
| * used in the dual capacity to handle a reply received from Flutter after sending a message. |
| */ |
| interface BinaryReply { |
| /** |
| * Handles the specified reply. |
| * |
| * @param reply the reply payload, a direct-allocated {@link ByteBuffer} or null. Senders of |
| * outgoing replies must place the reply bytes between position zero and current position. |
| * Reply receivers can read from the buffer directly. |
| */ |
| void reply(@Nullable ByteBuffer reply); |
| } |
| } |